From 0eaa557c36055770a90f6ea54c88f30010e1e5d9 Mon Sep 17 00:00:00 2001 From: kramm Date: Mon, 6 Oct 2008 12:56:03 +0000 Subject: [PATCH] added median advance detection --- lib/pdf/InfoOutputDev.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++ lib/pdf/InfoOutputDev.h | 17 ++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/lib/pdf/InfoOutputDev.cc b/lib/pdf/InfoOutputDev.cc index 1653978..c2accf2 100644 --- a/lib/pdf/InfoOutputDev.cc +++ b/lib/pdf/InfoOutputDev.cc @@ -59,6 +59,9 @@ FontInfo::FontInfo() this->num_glyphs = 0; this->glyphs = 0; this->splash_font = 0; + this->lastchar = -1; + this->lastx = 0; + this->lasty = 0; } FontInfo::~FontInfo() { @@ -162,6 +165,8 @@ void InfoOutputDev::updateFont(GfxState *state) state->setFont(font, 1024.0); splash->doUpdateFont(state); currentfont->splash_font = splash->getCurrentFont(); + currentfont->ascender = currentfont->splash_font->ascender; + currentfont->descender = currentfont->splash_font->descender; free(id); } @@ -202,13 +207,63 @@ void InfoOutputDev::drawChar(GfxState *state, double x, double y, GlyphInfo*g = currentfont->glyphs[code]; if(!g) { g = currentfont->glyphs[code] = new GlyphInfo(); + g->advance_samples = 0; + currentfont->splash_font->last_advance = -1; g->path = currentfont->splash_font->getGlyphPath(code); + g->advance = currentfont->splash_font->last_advance; g->unicode = 0; } if(uLen && (u[0]>=32 && u[0]unicode || !g->unicode)) { g->unicode = u[0]; } + if(currentfont->lastchar>=0 && currentfont->lasty == y) { + double xshift = x - currentfont->lastx; + if(xshift>=0) { + AdvanceSample* old = g->advance_samples; + g->advance_samples = new AdvanceSample(); + g->advance_samples->next = old; + g->advance_samples->advance = xshift; + } + } + + currentfont->lastx = x; + currentfont->lasty = y; + currentfont->lastchar = code; +} + +static int compare_double(const void *_a, const void *_b) +{ + const double*a = (const double*)_a; + const double*b = (const double*)_b; + if(*a < *b) + return -1; + if(*a > *b) + return 1; + return 0; +} +double GlyphInfo::estimateAdvance() +{ + AdvanceSample*a = advance_samples; + int n=0; + while(a) { + n++; + a = a->next; + } + if(!n) + return -1; + double*list = (double*)malloc(sizeof(double)*n); + n = 0; + a = advance_samples; + while(a) { + list[n++] = a->advance; + a = a->next; + } + // FIXME: a true median algorithm would be faster + qsort(list, n, sizeof(double), compare_double); + double median = list[n/2]; + free(list); + return median; } GBool InfoOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen) diff --git a/lib/pdf/InfoOutputDev.h b/lib/pdf/InfoOutputDev.h index 539addd..699c4c7 100644 --- a/lib/pdf/InfoOutputDev.h +++ b/lib/pdf/InfoOutputDev.h @@ -42,18 +42,35 @@ #include "GHash.h" #endif +struct AdvanceSample +{ + double advance; + struct AdvanceSample*next; +}; + struct GlyphInfo { SplashPath*path; int unicode; int glyphid; + double advance; double x1,y1,x2,y2; + + double estimateAdvance(); + + AdvanceSample*advance_samples; }; struct FontInfo { FontInfo(); ~FontInfo(); + + double lastx,lasty; + int lastchar; + + double ascender,descender; + void grow(int size); GfxFont*font; -- 1.7.10.4