Code

NR::Maybe => boost::optional
[inkscape.git] / src / libnrtype / FontInstance.cpp
index d28fb42a420cf9f35e1e3aa23c9a5d3eba0d4e72..4f745c0f946d85859d2829555e86e30f16c80a48 100644 (file)
@@ -14,7 +14,7 @@
 #include <libnr/nr-rect.h>
 #include <libnrtype/font-glyph.h>
 #include <libnrtype/font-instance.h>
-
+#include <2geom/pathvector.h>
 #include <livarot/Path.h>
 
 #include "RasterFont.h"
@@ -67,7 +67,7 @@ bool  font_style_equal::operator()(const font_style &a,const font_style &b) {
        if ( a.stroke_width > 0.01 && b.stroke_width <= 0.01 ) return false;
        if ( a.stroke_width <= 0.01 && b.stroke_width > 0.01 ) return false;
        if ( a.stroke_width <= 0.01 && b.stroke_width <= 0.01 ) return true;
-       
+
        if ( a.stroke_cap != b.stroke_cap ) return false;
        if ( a.stroke_join != b.stroke_join ) return false;
     if ( (int)(a.stroke_miter_limit*100) != (int)(b.stroke_miter_limit*100) ) return false;
@@ -90,9 +90,20 @@ typedef struct ft2_to_liv {
        NR::Point    last;
 } ft2_to_liv;
 
+// Note: Freetype 2.2.1 redefined function signatures for functions to be placed in an
+// FT_Outline_Funcs structure.  This is needed to keep backwards compatibility with the
+// 2.1.x series.
+
+/* *** BEGIN #if HACK *** */
+#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 2
+typedef FT_Vector const FREETYPE_VECTOR;
+#else
+typedef FT_Vector FREETYPE_VECTOR;
+#endif
+
 // outline as returned by freetype -> livarot Path
 // see nr-type-ft2.cpp for the freetype -> artBPath on which this code is based
-static int ft2_move_to(FT_Vector const *to, void * i_user) {
+static int ft2_move_to(FREETYPE_VECTOR *to, void * i_user) {
        ft2_to_liv* user=(ft2_to_liv*)i_user;
        NR::Point   p(user->scale*to->x,user->scale*to->y);
        //      printf("m  t=%f %f\n",p[0],p[1]);
@@ -101,7 +112,7 @@ static int ft2_move_to(FT_Vector const *to, void * i_user) {
        return 0;
 }
 
-static int ft2_line_to(FT_Vector const *to, void *i_user)
+static int ft2_line_to(FREETYPE_VECTOR *to, void *i_user)
 {
        ft2_to_liv* user=(ft2_to_liv*)i_user;
        NR::Point   p(user->scale*to->x,user->scale*to->y);
@@ -111,10 +122,10 @@ static int ft2_line_to(FT_Vector const *to, void *i_user)
        return 0;
 }
 
-static int ft2_conic_to(FT_Vector const *control, FT_Vector const *to, void *i_user)
+static int ft2_conic_to(FREETYPE_VECTOR *control, FREETYPE_VECTOR *to, void *i_user)
 {
        ft2_to_liv* user=(ft2_to_liv*)i_user;
-       NR::Point   p(user->scale*to->x,user->scale*to->y),c(user->scale*control->x,user->scale*control->y);  
+       NR::Point   p(user->scale*to->x,user->scale*to->y),c(user->scale*control->x,user->scale*control->y);
        //      printf("b c=%f %f  t=%f %f\n",c[0],c[1],p[0],p[1]);
        user->theP->BezierTo(p);
        user->theP->IntermBezierTo(c);
@@ -123,19 +134,21 @@ static int ft2_conic_to(FT_Vector const *control, FT_Vector const *to, void *i_u
        return 0;
 }
 
-static int ft2_cubic_to(FT_Vector const *control1, FT_Vector const *control2, FT_Vector const *to, void *i_user)
+static int ft2_cubic_to(FREETYPE_VECTOR *control1, FREETYPE_VECTOR *control2, FREETYPE_VECTOR *to, void *i_user)
 {
        ft2_to_liv* user=(ft2_to_liv*)i_user;
        NR::Point   p(user->scale*to->x,user->scale*to->y),
        c1(user->scale*control1->x,user->scale*control1->y),
-       c2(user->scale*control2->x,user->scale*control2->y);  
+       c2(user->scale*control2->x,user->scale*control2->y);
        //      printf("c c1=%f %f  c2=%f %f   t=%f %f\n",c1[0],c1[1],c2[0],c2[1],p[0],p[1]);
-       user->theP->CubicTo(p,3*(c1-user->last),3*(p-c2)); 
+       user->theP->CubicTo(p,3*(c1-user->last),3*(p-c2));
        user->last=p;
        return 0;
 }
 #endif
 
+/* *** END #if HACK *** */
+
 /*
  *
  */
@@ -165,7 +178,7 @@ font_instance::~font_instance(void)
 
        for (int i=0;i<nbGlyph;i++) {
                if ( glyphs[i].outline ) delete glyphs[i].outline;
-               if ( glyphs[i].artbpath ) free(glyphs[i].artbpath);
+        if ( glyphs[i].pathvector ) delete glyphs[i].pathvector;
        }
        if ( glyphs ) free(glyphs);
        nbGlyph=maxGlyph=0;
@@ -216,7 +229,7 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
        }
        char*   res=NULL;
        bool    free_res=false;
-       
+
        if ( strcmp(key,"name") == 0 ) {
                PangoFontDescription* td=pango_font_description_copy(descr);
                pango_font_description_unset_fields (td, PANGO_FONT_MASK_SIZE);
@@ -234,11 +247,11 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
              bool o = (style == PANGO_STYLE_OBLIQUE);
              PangoWeight weight=pango_font_description_get_weight(descr);
              bool b = (weight >= PANGO_WEIGHT_BOLD);
-   
-             res = g_strdup_printf ("%s%s%s%s", 
-                                    pango_font_description_get_family(descr), 
-                                    (b || i || o) ? "-" : "", 
-                                    (b) ? "Bold" : "", 
+
+             res = g_strdup_printf ("%s%s%s%s",
+                                    pango_font_description_get_family(descr),
+                                    (b || i || o) ? "-" : "",
+                                    (b) ? "Bold" : "",
                                     (i) ? "Italic" : ((o) ? "Oblique" : "")  );
              free_res = true;
          }
@@ -248,51 +261,53 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
        } else if ( strcmp(key,"style") == 0 ) {
                PangoStyle v=pango_font_description_get_style(descr);
                if ( v == PANGO_STYLE_ITALIC ) {
-                       res="italic";
+                       res=(char*)"italic";
                } else if ( v == PANGO_STYLE_OBLIQUE ) {
-                       res="oblique";
+                       res=(char*)"oblique";
                } else {
-                       res="normal";
+                       res=(char*)"normal";
                }
                free_res=false;
        } else if ( strcmp(key,"weight") == 0 ) {
                PangoWeight v=pango_font_description_get_weight(descr);
                if ( v <= PANGO_WEIGHT_ULTRALIGHT ) {
-                       res="200";
+                       res=(char*)"200";
                } else if ( v <= PANGO_WEIGHT_LIGHT ) {
-                       res="300";
+                       res=(char*)"300";
                } else if ( v <= PANGO_WEIGHT_NORMAL ) {
-                       res="normal";
+                       res=(char*)"normal";
                } else if ( v <= PANGO_WEIGHT_BOLD ) {
-                       res="bold";
-               } else {
-                       res="800";
+                       res=(char*)"bold";
+               } else if ( v <= PANGO_WEIGHT_ULTRABOLD ) {
+                   res=(char*)"800";
+               } else { // HEAVY
+                       res=(char*)"900";
                }
                free_res=false;
        } else if ( strcmp(key,"stretch") == 0 ) {
                PangoStretch v=pango_font_description_get_stretch(descr);
                if ( v <= PANGO_STRETCH_EXTRA_CONDENSED ) {
-                       res="extra-condensed";
+                       res=(char*)"extra-condensed";
                } else if ( v <= PANGO_STRETCH_CONDENSED ) {
-                       res="condensed";
+                       res=(char*)"condensed";
                } else if ( v <= PANGO_STRETCH_SEMI_CONDENSED ) {
-                       res="semi-condensed";
+                       res=(char*)"semi-condensed";
                } else if ( v <= PANGO_STRETCH_NORMAL ) {
-                       res="normal";
+                       res=(char*)"normal";
                } else if ( v <= PANGO_STRETCH_SEMI_EXPANDED ) {
-                       res="semi-expanded";
+                       res=(char*)"semi-expanded";
                } else if ( v <= PANGO_STRETCH_EXPANDED ) {
-                       res="expanded";
+                       res=(char*)"expanded";
                } else {
-                       res="extra-expanded";
+                       res=(char*)"extra-expanded";
                }
                free_res=false;
        } else if ( strcmp(key,"variant") == 0 ) {
                PangoVariant v=pango_font_description_get_variant(descr);
                if ( v == PANGO_VARIANT_SMALL_CAPS ) {
-                       res="small-caps";
+                       res=(char*)"small-caps";
                } else {
-                       res="normal";
+                       res=(char*)"normal";
                }
                free_res=false;
        } else {
@@ -303,7 +318,7 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
                if ( size > 0 ) str[0]=0;
                return 0;
        }
-       
+
        if (res) {
                unsigned int len=strlen(res);
                unsigned int rlen=(size-1<len)?size-1:len;
@@ -414,11 +429,16 @@ void font_instance::LoadGlyph(int glyph_id)
                }
                font_glyph  n_g;
                n_g.outline=NULL;
-               n_g.artbpath=NULL;
+        n_g.pathvector=NULL;
                n_g.bbox[0]=n_g.bbox[1]=n_g.bbox[2]=n_g.bbox[3]=0;
                bool   doAdd=false;
 
 #ifdef USE_PANGO_WIN32
+
+#ifndef GGO_UNHINTED         // For compatibility with old SDKs.
+#define GGO_UNHINTED 0x0100
+#endif
+
         MAT2 identity = {{0,1},{0,0},{0,0},{0,1}};
         OUTLINETEXTMETRIC otm;
         GetOutlineTextMetrics(daddy->hScreenDC, sizeof(otm), &otm);
@@ -536,7 +556,7 @@ void font_instance::LoadGlyph(int glyph_id)
                if ( doAdd ) {
                        if ( n_g.outline ) {
                                n_g.outline->FastBBox(n_g.bbox[0],n_g.bbox[1],n_g.bbox[2],n_g.bbox[3]);
-                               n_g.artbpath=n_g.outline->MakeArtBPath();
+                n_g.pathvector=n_g.outline->MakePathVector();
                        }
                        glyphs[nbGlyph]=n_g;
                        id_to_no[glyph_id]=nbGlyph;
@@ -584,7 +604,7 @@ bool font_instance::FontSlope(double &run, double &rise)
     rise=otm.otmsCharSlopeRise;
 #else
        if ( !FT_IS_SCALABLE(theFace) ) return false; // bitmap font
-       
+
     TT_HoriHeader *hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(theFace, ft_sfnt_hhea);
     if (hhea == NULL) return false;
     run = hhea->caret_Slope_Run;
@@ -593,7 +613,7 @@ bool font_instance::FontSlope(double &run, double &rise)
        return true;
 }
 
-NR::Rect font_instance::BBox(int glyph_id)
+boost::optional<NR::Rect> font_instance::BBox(int glyph_id)
 {
        int no=-1;
        if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
@@ -606,11 +626,13 @@ NR::Rect font_instance::BBox(int glyph_id)
        } else {
                no=id_to_no[glyph_id];
        }
-       if ( no < 0 ) return NR::Rect(NR::Point(0,0),NR::Point(0,0));
-       NR::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]);
-       NR::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]);
-       NR::Rect  res(rmin,rmax);
-       return res;
+       if ( no < 0 ) {
+            return boost::optional<NR::Rect>();
+        } else {
+           NR::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]);
+           NR::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]);
+           return NR::Rect(rmin, rmax);
+        }
 }
 
 Path* font_instance::Outline(int glyph_id,Path* copyInto)
@@ -636,21 +658,21 @@ Path* font_instance::Outline(int glyph_id,Path* copyInto)
        return src_o;
 }
 
-void* font_instance::ArtBPath(int glyph_id)
+Geom::PathVector* font_instance::PathVector(int glyph_id)
 {
-       int no=-1;
-       if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
-               LoadGlyph(glyph_id);
-               if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
-                       // didn't load
-               } else {
-                       no=id_to_no[glyph_id];
-               }
-       } else {
-               no=id_to_no[glyph_id];
-       }
-       if ( no < 0 ) return NULL;
-       return glyphs[no].artbpath;
+    int no = -1;
+    if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
+        LoadGlyph(glyph_id);
+        if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
+            // didn't load
+        } else {
+            no = id_to_no[glyph_id];
+        }
+    } else {
+        no = id_to_no[glyph_id];
+    }
+    if ( no < 0 ) return NULL;
+    return glyphs[no].pathvector;
 }
 
 double font_instance::Advance(int glyph_id,bool vertical)
@@ -674,10 +696,10 @@ double font_instance::Advance(int glyph_id,bool vertical)
                }
        }
        return 0;
-}      
+}
 
 
-raster_font* font_instance::RasterFont(const NR::Matrix &trs,double stroke_width,bool vertical,JoinType stroke_join,ButtType stroke_cap,float miter_limit)
+raster_font* font_instance::RasterFont(const NR::Matrix &trs, double stroke_width, bool vertical, JoinType stroke_join, ButtType stroke_cap, float /*miter_limit*/)
 {
        font_style  nStyle;
        nStyle.transform=trs;