added median advance detection
authorkramm <kramm>
Mon, 6 Oct 2008 12:56:03 +0000 (12:56 +0000)
committerkramm <kramm>
Mon, 6 Oct 2008 12:56:03 +0000 (12:56 +0000)
lib/pdf/InfoOutputDev.cc
lib/pdf/InfoOutputDev.h

index 1653978..c2accf2 100644 (file)
@@ -59,6 +59,9 @@ FontInfo::FontInfo()
     this->num_glyphs = 0;
     this->glyphs = 0;
     this->splash_font = 0;
     this->num_glyphs = 0;
     this->glyphs = 0;
     this->splash_font = 0;
+    this->lastchar = -1;
+    this->lastx = 0;
+    this->lasty = 0;
 }
 FontInfo::~FontInfo()
 {
 }
 FontInfo::~FontInfo()
 {
@@ -162,6 +165,8 @@ void InfoOutputDev::updateFont(GfxState *state)
     state->setFont(font, 1024.0);
     splash->doUpdateFont(state);
     currentfont->splash_font = splash->getCurrentFont();
     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);
 }
 
     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();
     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->path = currentfont->splash_font->getGlyphPath(code);
+       g->advance = currentfont->splash_font->last_advance;
        g->unicode = 0;
     }
     if(uLen && (u[0]>=32 && u[0]<g->unicode || !g->unicode)) {
        g->unicode = u[0];
     }
        g->unicode = 0;
     }
     if(uLen && (u[0]>=32 && u[0]<g->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)
 }
 
 GBool InfoOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen)
index 539addd..699c4c7 100644 (file)
 #include "GHash.h"
 #endif
 
 #include "GHash.h"
 #endif
 
+struct AdvanceSample
+{
+    double advance;
+    struct AdvanceSample*next;
+};
+
 struct GlyphInfo
 {
     SplashPath*path;
     int unicode;
     int glyphid;
 struct GlyphInfo
 {
     SplashPath*path;
     int unicode;
     int glyphid;
+    double advance;
     double x1,y1,x2,y2;
     double x1,y1,x2,y2;
+
+    double estimateAdvance();
+
+    AdvanceSample*advance_samples;
 };
 
 struct FontInfo
 {
     FontInfo();
     ~FontInfo();
 };
 
 struct FontInfo
 {
     FontInfo();
     ~FontInfo();
+
+    double lastx,lasty;
+    int lastchar;
+
+    double ascender,descender;
+
     void grow(int size);
 
     GfxFont*font;
     void grow(int size);
 
     GfxFont*font;