mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2024-12-26 13:28:22 +01:00
Finish implementation of pdfioContentTextMeasure (Issue #17)
This commit is contained in:
parent
4919783da5
commit
c188cb8dad
@ -233,8 +233,7 @@ DOCFLAGS = \
|
||||
doc:
|
||||
echo Generating documentation...
|
||||
codedoc $(DOCFLAGS) --title "PDFio Programming Manual v$(PDFIO_VERSION)" $(PUBHEADERS) $(PUBOBJS:.o=.c) --body doc/pdfio.md --coverimage doc/pdfio-512.png pdfio.xml >doc/pdfio.html
|
||||
codedoc $(DOCFLAGS) --title "PDFio Programming Manual v$(PDFIO_VERSIONmc6809e
|
||||
)" --body doc/pdfio.md --coverimage doc/pdfio-epub.png pdfio.xml --epub doc/pdfio.epub
|
||||
codedoc $(DOCFLAGS) --title "PDFio Programming Manual v$(PDFIO_VERSION)" --body doc/pdfio.md --coverimage doc/pdfio-epub.png pdfio.xml --epub doc/pdfio.epub
|
||||
codedoc $(DOCFLAGS) --title "pdf read/write library" --man pdfio --section 3 --body doc/pdfio.md pdfio.xml >doc/pdfio.3
|
||||
rm -f pdfio.xml
|
||||
|
||||
|
@ -1061,20 +1061,97 @@ pdfioContentTextEnd(pdfio_stream_t *st) // I - Stream
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioContextTextMeasure()' - Measure a text string and return its width.
|
||||
// 'pdfioContentTextMeasure()' - Measure a text string and return its width.
|
||||
//
|
||||
// This function measures the given text string "s" and returns its width based
|
||||
// on "size". The text string must always use the UTF-8 (Unicode) encoding but
|
||||
// any control characters (such as newlines) are ignored.
|
||||
//
|
||||
|
||||
double // O - Width
|
||||
pdfioContextTextMeasure(
|
||||
pdfioContentTextMeasure(
|
||||
pdfio_obj_t *font, // I - Font object created by @link pdfioFileCreateFontObjFromFile@
|
||||
const char *s, // I - UTF-8 string
|
||||
double size) // I - Font size/height
|
||||
{
|
||||
const char *subtype; // Font sub-type
|
||||
ttf_t *ttf = (ttf_t *)_pdfioObjGetExtension(font);
|
||||
// TrueType font data
|
||||
ttf_rect_t extents; // Text extents
|
||||
int ch; // Unicode character
|
||||
char temp[1024], // Temporary string
|
||||
*tempptr; // Pointer into temporary string
|
||||
|
||||
|
||||
if ((subtype = pdfioObjGetSubtype(font)) == NULL || strcmp(subtype, "Type0"))
|
||||
{
|
||||
// Map non-CP1282 characters to '?', everything else as-is...
|
||||
tempptr = temp;
|
||||
|
||||
while (*s && tempptr < (temp + sizeof(temp) - 3))
|
||||
{
|
||||
if ((*s & 0xe0) == 0xc0)
|
||||
{
|
||||
// Two-byte UTF-8
|
||||
ch = ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
|
||||
s += 2;
|
||||
}
|
||||
else if ((*s & 0xf0) == 0xe0)
|
||||
{
|
||||
// Three-byte UTF-8
|
||||
ch = ((s[0] & 0x0f) << 12) | ((s[1] & 0x3f) << 6) | (s[2] & 0x3f);
|
||||
s += 3;
|
||||
}
|
||||
else if ((*s & 0xf8) == 0xf0)
|
||||
{
|
||||
// Four-byte UTF-8
|
||||
ch = ((s[0] & 0x07) << 18) | ((s[1] & 0x3f) << 12) | ((s[2] & 0x3f) << 6) | (s[3] & 0x3f);
|
||||
s += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch = *s++;
|
||||
}
|
||||
|
||||
if (ch > 255)
|
||||
{
|
||||
// Try mapping from Unicode to CP1252...
|
||||
size_t i; // Looping var
|
||||
|
||||
for (i = 0; i < (sizeof(_pdfio_cp1252) / sizeof(_pdfio_cp1252[0])); i ++)
|
||||
{
|
||||
if (ch == _pdfio_cp1252[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= (sizeof(_pdfio_cp1252) / sizeof(_pdfio_cp1252[0])))
|
||||
ch = '?'; // Unsupported chars map to ?
|
||||
}
|
||||
|
||||
if (ch < 128)
|
||||
{
|
||||
// ASCII
|
||||
*tempptr++ = ch;
|
||||
}
|
||||
else if (ch < 2048)
|
||||
{
|
||||
// 2-byte UTF-8
|
||||
*tempptr++ = 0xc0 | ((ch >> 6) & 0x1f);
|
||||
*tempptr++ = 0x80 | (ch & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3-byte UTF-8
|
||||
*tempptr++ = 0xe0 | ((ch >> 12) & 0x0f);
|
||||
*tempptr++ = 0x80 | ((ch >> 6) & 0x3f);
|
||||
*tempptr++ = 0x80 | (ch & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
*tempptr = '\0';
|
||||
s = temp;
|
||||
}
|
||||
|
||||
ttfGetExtents(ttf, size, s, &extents);
|
||||
|
||||
return (extents.right - extents.left);
|
||||
@ -1654,7 +1731,7 @@ pdfioFileCreateFontObjFromFile(
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
ttfDelete(font);
|
||||
_pdfioObjSetExtension(obj, font, (_pdfio_extfree_t)ttfDelete);
|
||||
|
||||
return (obj);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ extern bool pdfioContentSetTextXScaling(pdfio_stream_t *st, double percent) _PD
|
||||
extern bool pdfioContentStroke(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||
extern bool pdfioContentTextBegin(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||
extern bool pdfioContentTextEnd(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||
extern double pdfioContextTextMeasure(pdfio_obj_t *font, const char *s, double size) _PDFIO_PUBLIC;
|
||||
extern double pdfioContentTextMeasure(pdfio_obj_t *font, const char *s, double size) _PDFIO_PUBLIC;
|
||||
extern bool pdfioContentTextMoveLine(pdfio_stream_t *st, double tx, double ty) _PDFIO_PUBLIC;
|
||||
extern bool pdfioContentTextMoveTo(pdfio_stream_t *st, double tx, double ty) _PDFIO_PUBLIC;
|
||||
extern bool pdfioContentTextNextLine(pdfio_stream_t *st) _PDFIO_PUBLIC;
|
||||
|
@ -217,8 +217,13 @@ void
|
||||
_pdfioObjDelete(pdfio_obj_t *obj) // I - Object
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
pdfioStreamClose(obj->stream);
|
||||
|
||||
if (obj->datafree)
|
||||
(obj->datafree)(obj->data);
|
||||
}
|
||||
|
||||
free(obj);
|
||||
}
|
||||
|
||||
@ -513,7 +518,7 @@ void
|
||||
_pdfioObjSetExtension(
|
||||
pdfio_obj_t *obj, // I - Object
|
||||
void *data, // I - Data
|
||||
void (*datafree)(void *)) // I - Free function
|
||||
_pdfio_extfree_t datafree) // I - Free function
|
||||
{
|
||||
obj->data = data;
|
||||
obj->datafree = datafree;
|
||||
|
@ -92,6 +92,9 @@
|
||||
|
||||
# define PDFIO_MAX_DEPTH 32 // Maximum nesting depth for values
|
||||
|
||||
typedef void (*_pdfio_extfree_t)(void *);
|
||||
// Extension data free function
|
||||
|
||||
typedef enum _pdfio_mode_e // Read/write mode
|
||||
{
|
||||
_PDFIO_MODE_READ, // Read a PDF file
|
||||
@ -288,7 +291,7 @@ struct _pdfio_obj_s // Object
|
||||
_pdfio_value_t value; // Dictionary/number/etc. value
|
||||
pdfio_stream_t *stream; // Open stream, if any
|
||||
void *data; // Extension data, if any
|
||||
void (*datafree)(void *); // Free callback for extension data
|
||||
_pdfio_extfree_t datafree; // Free callback for extension data
|
||||
};
|
||||
|
||||
struct _pdfio_stream_s // Stream
|
||||
@ -369,7 +372,7 @@ extern bool _pdfioFileWrite(pdfio_file_t *pdf, const void *buffer, size_t bytes
|
||||
extern void _pdfioObjDelete(pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
extern void *_pdfioObjGetExtension(pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
extern bool _pdfioObjLoad(pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
extern void _pdfioObjSetExtension(pdfio_obj_t *obj, void *data, void (*datafree)(void *)) _PDFIO_INTERNAL;
|
||||
extern void _pdfioObjSetExtension(pdfio_obj_t *obj, void *data, _pdfio_extfree_t datafree) _PDFIO_INTERNAL;
|
||||
|
||||
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, pdfio_filter_t compression) _PDFIO_INTERNAL;
|
||||
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
|
||||
|
27
testpdfio.c
27
testpdfio.c
@ -2242,6 +2242,7 @@ write_font_test(
|
||||
char title[256], // Page title
|
||||
textname[256], // Name of text font
|
||||
*ptr; // Pointer into name
|
||||
double width; // Text width
|
||||
int i; // Looping var
|
||||
static const char * const welcomes[] =// "Welcome" in many languages
|
||||
{
|
||||
@ -2463,8 +2464,8 @@ write_font_test(
|
||||
else
|
||||
goto error;
|
||||
|
||||
fputs("pdfioContentTextMoveTo(36.0, 702.0): ", stdout);
|
||||
if (pdfioContentTextMoveTo(st, 36.0, 702.0))
|
||||
fputs("pdfioContentTextMoveTo(198.0, 702.0): ", stdout);
|
||||
if (pdfioContentTextMoveTo(st, 198.0, 702.0))
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
@ -2473,18 +2474,36 @@ write_font_test(
|
||||
{
|
||||
if (i > 0 && (i % 50) == 0)
|
||||
{
|
||||
fputs("pdfioContentTextMoveTo(200.0, 600.0): ", stdout);
|
||||
if (pdfioContentTextMoveTo(st, 200.0, 600.0))
|
||||
fputs("pdfioContentTextMoveTo(162.0, 600.0): ", stdout);
|
||||
if (pdfioContentTextMoveTo(st, 162.0, 600.0))
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf("pdfioContentTextMeasure(\"%s\"): ", welcomes[i]);
|
||||
if ((width = pdfioContentTextMeasure(textfont, welcomes[i], 10.0)) >= 0.0)
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
|
||||
printf("pdfioContextTextMoveTo(%g, 0.0): ", -width);
|
||||
if (pdfioContentTextMoveTo(st, -width, 0.0))
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
|
||||
printf("pdfioContentTextShowf(\"%s\"): ", welcomes[i]);
|
||||
if (pdfioContentTextShowf(st, unicode, "%s\n", welcomes[i]))
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
|
||||
printf("pdfioContextTextMoveTo(%g, 0.0): ", width);
|
||||
if (pdfioContentTextMoveTo(st, width, 0.0))
|
||||
puts("PASS");
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
fputs("pdfioContentTextEnd(): ", stdout);
|
||||
|
Loading…
Reference in New Issue
Block a user