Skip to content

Commit

Permalink
- implemented i_t1_has_chars(), tests for same
Browse files Browse the repository at this point in the history
        - added ExistenceTest.{pfb,afm,ttf} for testing $font->has_chars
        - tests for Imager::Font::Type1::has_chars();
        - tests for Imager::Font::Truetype::has_chars();
        - internal and external bounding box calculations now use
          the same hint flags as text output for Freetype 2.x
        - made the i_foo_bbox() interface more expandable by using
          symbolic constants for the sizes and array offsets
        - added a / character to the ExistenceTest.foo fonts that
          overlaps the right side of the character cell, to test the
          advance width reporting.
        - added advance width to the i_foo_bbox() interface, and
          implemented it for FT2, FT1 and Type 1
        - Imager::Font::bounding_box() now returns an Imager::Font::BBox
          object in scalar context.
        - implemented $font->align() text output method, for simple output
          of aligned text
        - created Imager::Font::Wrap::wrap_text to perform simple text
          wrapping
        - FT1, FT2 and T1 fonts now support the face_name method
        - FT1, FT2 and T1 now support the glyph_names() method
  • Loading branch information
Tony Cook committed Dec 31, 2002
1 parent 0cb68c1 commit 3799c4d
Show file tree
Hide file tree
Showing 29 changed files with 2,617 additions and 196 deletions.
21 changes: 21 additions & 0 deletions Changes
Expand Up @@ -690,6 +690,27 @@ Revision history for Perl extension Imager.
- the code to read multiple tiffs didn't handle files with more - the code to read multiple tiffs didn't handle files with more
than five images correctly, causing a memory overrun. than five images correctly, causing a memory overrun.
- fix some minor test code hiccups - fix some minor test code hiccups
- implemented i_t1_has_chars(), tests for same
- added ExistenceTest.{pfb,afm,ttf} for testing $font->has_chars
- tests for Imager::Font::Type1::has_chars();
- tests for Imager::Font::Truetype::has_chars();
- internal and external bounding box calculations now use
the same hint flags as text output for Freetype 2.x
- made the i_foo_bbox() interface more expandable by using
symbolic constants for the sizes and array offsets
- added a / character to the ExistenceTest.foo fonts that
overlaps the right side of the character cell, to test the
advance width reporting.
- added advance width to the i_foo_bbox() interface, and
implemented it for FT2, FT1 and Type 1
- Imager::Font::bounding_box() now returns an Imager::Font::BBox
object in scalar context.
- implemented $font->align() text output method, for simple output
of aligned text
- created Imager::Font::Wrap::wrap_text to perform simple text
wrapping
- FT1, FT2 and T1 fonts now support the face_name method
- FT1, FT2 and T1 now support the glyph_names() method


================================================================= =================================================================


Expand Down
2 changes: 1 addition & 1 deletion Imager.pm
Expand Up @@ -2708,7 +2708,7 @@ In cases where no image object is associated with an operation
C<$Imager::ERRSTR> is used to report errors not directly associated C<$Imager::ERRSTR> is used to report errors not directly associated
with an image object. with an image object.
The C<Imager-><gt>new> method is described in detail in the The C<Imager-E<gt>new> method is described in detail in the
Imager::ImageTypes manpage. Imager::ImageTypes manpage.
=head1 SUPPORT =head1 SUPPORT
Expand Down
259 changes: 229 additions & 30 deletions Imager.xs
Expand Up @@ -1715,18 +1715,21 @@ i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
PREINIT: PREINIT:
char *str; char *str;
STRLEN len; STRLEN len;
int cords[6]; int cords[BOUNDING_BOX_COUNT];
int i; int i;
int rc;
PPCODE: PPCODE:
#ifdef SvUTF8 #ifdef SvUTF8
if (SvUTF8(str_sv)) if (SvUTF8(str_sv))
utf8 = 1; utf8 = 1;
#endif #endif
str = SvPV(str_sv, len); str = SvPV(str_sv, len);
i_t1_bbox(fontnum,point,str,len,cords,utf8,flags); rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
EXTEND(SP, 6); if (rc > 0) {
for (i = 0; i < 6; ++i) EXTEND(SP, rc);
PUSHs(sv_2mortal(newSViv(cords[i]))); for (i = 0; i < rc; ++i)
PUSHs(sv_2mortal(newSViv(cords[i])));
}






Expand Down Expand Up @@ -1756,6 +1759,89 @@ i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
OUTPUT: OUTPUT:
RETVAL RETVAL


void
i_t1_has_chars(handle, text_sv, utf8 = 0)
int handle
SV *text_sv
int utf8
PREINIT:
char const *text;
STRLEN len;
char *work;
int count;
int i;
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
text = SvPV(text_sv, len);
work = mymalloc(len);
count = i_t1_has_chars(handle, text, len, utf8, work);
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
for (i = 0; i < count; ++i) {
PUSHs(sv_2mortal(newSViv(work[i])));
}
}
else {
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(work, count)));
}
myfree(work);

void
i_t1_face_name(handle)
int handle
PREINIT:
char name[255];
int len;
PPCODE:
len = i_t1_face_name(handle, name, sizeof(name));
if (len) {
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
}

void i_t1_glyph_name(handle, text_sv, utf8 = 0)
int handle
SV *text_sv
int utf8
PREINIT:
char const *text;
STRLEN work_len;
int len;
int outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
text = SvPV(text_sv, work_len);
len = work_len;
while (len) {
unsigned char ch;
if (utf8) {
ch = i_utf8_advance(&text, &len);
if (ch == ~0UL) {
i_push_error(0, "invalid UTF8 character");
break;
}
}
else {
ch = *text++;
--len;
}
EXTEND(SP, 1);
if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
PUSHs(sv_2mortal(newSVpv(name, 0)));
}
else {
PUSHs(&PL_sv_undef);
}
}

#endif #endif


#ifdef HAVE_LIBTT #ifdef HAVE_LIBTT
Expand Down Expand Up @@ -1840,23 +1926,21 @@ i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
int len_ignored int len_ignored
int utf8 int utf8
PREINIT: PREINIT:
int cords[6],rc; int cords[BOUNDING_BOX_COUNT],rc;
char * str; char * str;
STRLEN len; STRLEN len;
int i;
PPCODE: PPCODE:
#ifdef SvUTF8 #ifdef SvUTF8
if (SvUTF8(ST(2))) if (SvUTF8(ST(2)))
utf8 = 1; utf8 = 1;
#endif #endif
str = SvPV(str_sv, len); str = SvPV(str_sv, len);
if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) { if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
EXTEND(SP, 4); EXTEND(SP, rc);
PUSHs(sv_2mortal(newSViv(cords[0]))); for (i = 0; i < rc; ++i) {
PUSHs(sv_2mortal(newSViv(cords[1]))); PUSHs(sv_2mortal(newSViv(cords[i])));
PUSHs(sv_2mortal(newSViv(cords[2]))); }
PUSHs(sv_2mortal(newSViv(cords[3])));
PUSHs(sv_2mortal(newSViv(cords[4])));
PUSHs(sv_2mortal(newSViv(cords[5])));
} }


void void
Expand Down Expand Up @@ -1890,9 +1974,63 @@ i_tt_has_chars(handle, text_sv, utf8)
} }
myfree(work); myfree(work);


#endif void
i_tt_dump_names(handle)
Imager::Font::TT handle


void
i_tt_face_name(handle)
Imager::Font::TT handle
PREINIT:
char name[255];
int len;
PPCODE:
len = i_tt_face_name(handle, name, sizeof(name));
if (len) {
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
}


void i_tt_glyph_name(handle, text_sv, utf8 = 0)
Imager::Font::TT handle
SV *text_sv
int utf8
PREINIT:
char const *text;
STRLEN work_len;
int len;
int outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
text = SvPV(text_sv, work_len);
len = work_len;
while (len) {
unsigned char ch;
if (utf8) {
ch = i_utf8_advance(&text, &len);
if (ch == ~0UL) {
i_push_error(0, "invalid UTF8 character");
break;
}
}
else {
ch = *text++;
--len;
}
EXTEND(SP, 1);
if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
PUSHs(sv_2mortal(newSVpv(name, 0)));
}
else {
PUSHs(&PL_sv_undef);
}
}

#endif




#ifdef HAVE_LIBJPEG #ifdef HAVE_LIBJPEG
Expand Down Expand Up @@ -3813,17 +3951,14 @@ i_wf_bbox(face, size, text)
char *face char *face
int size int size
char *text char *text
int rc, i;
PREINIT: PREINIT:
int cords[6]; int cords[BOUNDING_BOX_COUNT];
PPCODE: PPCODE:
if (i_wf_bbox(face, size, text, strlen(text), cords)) { if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
EXTEND(SP, 6); EXTEND(SP, rc);
PUSHs(sv_2mortal(newSViv(cords[0]))); for (i = 0; i < rc; ++i)
PUSHs(sv_2mortal(newSViv(cords[1]))); PUSHs(sv_2mortal(newSViv(cords[i])));
PUSHs(sv_2mortal(newSViv(cords[2])));
PUSHs(sv_2mortal(newSViv(cords[3])));
PUSHs(sv_2mortal(newSViv(cords[4])));
PUSHs(sv_2mortal(newSViv(cords[5])));
} }


undef_int undef_int
Expand Down Expand Up @@ -3930,23 +4065,28 @@ i_ft2_settransform(font, matrix)
RETVAL RETVAL


void void
i_ft2_bbox(font, cheight, cwidth, text, utf8) i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
Imager::Font::FT2 font Imager::Font::FT2 font
double cheight double cheight
double cwidth double cwidth
char *text SV *text_sv
int utf8 int utf8
PREINIT: PREINIT:
int bbox[6]; int bbox[BOUNDING_BOX_COUNT];
int i; int i;
char *text;
STRLEN text_len;
int rc;
PPCODE: PPCODE:
text = SvPV(text_sv, text_len);
#ifdef SvUTF8 #ifdef SvUTF8
if (SvUTF8(ST(3))) if (SvUTF8(text_sv))
utf8 = 1; utf8 = 1;
#endif #endif
if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox, utf8)) { rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
EXTEND(SP, 6); if (rc) {
for (i = 0; i < 6; ++i) EXTEND(SP, rc);
for (i = 0; i < rc; ++i)
PUSHs(sv_2mortal(newSViv(bbox[i]))); PUSHs(sv_2mortal(newSViv(bbox[i])));
} }


Expand Down Expand Up @@ -4074,6 +4214,65 @@ i_ft2_has_chars(handle, text_sv, utf8)
} }
myfree(work); myfree(work);


void
i_ft2_face_name(handle)
Imager::Font::FT2 handle
PREINIT:
char name[255];
int len;
PPCODE:
len = i_ft2_face_name(handle, name, sizeof(name));
if (len) {
EXTEND(SP, 1);
PUSHs(sv_2mortal(newSVpv(name, 0)));
}

void i_ft2_glyph_name(handle, text_sv, utf8 = 0)
Imager::Font::FT2 handle
SV *text_sv
int utf8
PREINIT:
char const *text;
STRLEN work_len;
int len;
int outsize;
char name[255];
PPCODE:
#ifdef SvUTF8
if (SvUTF8(text_sv))
utf8 = 1;
#endif
text = SvPV(text_sv, work_len);
len = work_len;
while (len) {
unsigned char ch;
if (utf8) {
ch = i_utf8_advance(&text, &len);
if (ch == ~0UL) {
i_push_error(0, "invalid UTF8 character");
break;
}
}
else {
ch = *text++;
--len;
}
EXTEND(SP, 1);
if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name))) {
PUSHs(sv_2mortal(newSVpv(name, 0)));
}
else {
PUSHs(&PL_sv_undef);
}
}

int
i_ft2_can_do_glyph_names()

int
i_ft2_face_has_glyph_names(handle)
Imager::Font::FT2 handle

#endif #endif


MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_ MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
Expand Down

0 comments on commit 3799c4d

Please sign in to comment.