index d28fb42a420cf9f35e1e3aa23c9a5d3eba0d4e72..4f745c0f946d85859d2829555e86e30f16c80a48 100644 (file)
#include <libnr/nr-rect.h>
#include <libnrtype/font-glyph.h>
#include <libnrtype/font-instance.h>
#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"
#include <livarot/Path.h>
#include "RasterFont.h"
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_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;
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;
NR::Point last;
} 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
// 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]);
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]);
return 0;
}
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);
{
ft2_to_liv* user=(ft2_to_liv*)i_user;
NR::Point p(user->scale*to->x,user->scale*to->y);
return 0;
}
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;
{
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);
// 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;
}
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),
{
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]);
// 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
user->last=p;
return 0;
}
#endif
+/* *** END #if HACK *** */
+
/*
*
*/
/*
*
*/
for (int i=0;i<nbGlyph;i++) {
if ( glyphs[i].outline ) delete glyphs[i].outline;
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;
}
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;
}
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);
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);
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;
}
(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 ) {
} 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 ) {
} else if ( v == PANGO_STYLE_OBLIQUE ) {
- res="oblique";
+ res=(char*)"oblique";
} else {
} 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 ) {
}
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 ) {
} else if ( v <= PANGO_WEIGHT_LIGHT ) {
- res="300";
+ res=(char*)"300";
} else if ( v <= PANGO_WEIGHT_NORMAL ) {
} else if ( v <= PANGO_WEIGHT_NORMAL ) {
- res="normal";
+ res=(char*)"normal";
} else if ( v <= PANGO_WEIGHT_BOLD ) {
} 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 ) {
}
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 ) {
} else if ( v <= PANGO_STRETCH_CONDENSED ) {
- res="condensed";
+ res=(char*)"condensed";
} else if ( v <= PANGO_STRETCH_SEMI_CONDENSED ) {
} else if ( v <= PANGO_STRETCH_SEMI_CONDENSED ) {
- res="semi-condensed";
+ res=(char*)"semi-condensed";
} else if ( v <= PANGO_STRETCH_NORMAL ) {
} else if ( v <= PANGO_STRETCH_NORMAL ) {
- res="normal";
+ res=(char*)"normal";
} else if ( v <= PANGO_STRETCH_SEMI_EXPANDED ) {
} else if ( v <= PANGO_STRETCH_SEMI_EXPANDED ) {
- res="semi-expanded";
+ res=(char*)"semi-expanded";
} else if ( v <= PANGO_STRETCH_EXPANDED ) {
} else if ( v <= PANGO_STRETCH_EXPANDED ) {
- res="expanded";
+ res=(char*)"expanded";
} else {
} 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 ) {
}
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 {
} else {
- res="normal";
+ res=(char*)"normal";
}
free_res=false;
} else {
}
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 ( size > 0 ) str[0]=0;
return 0;
}
-
+
if (res) {
unsigned int len=strlen(res);
unsigned int rlen=(size-1<len)?size-1:len;
if (res) {
unsigned int len=strlen(res);
unsigned int rlen=(size-1<len)?size-1:len;
}
font_glyph n_g;
n_g.outline=NULL;
}
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
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);
MAT2 identity = {{0,1},{0,0},{0,0},{0,1}};
OUTLINETEXTMETRIC otm;
GetOutlineTextMetrics(daddy->hScreenDC, sizeof(otm), &otm);
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]);
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;
}
glyphs[nbGlyph]=n_g;
id_to_no[glyph_id]=nbGlyph;
rise=otm.otmsCharSlopeRise;
#else
if ( !FT_IS_SCALABLE(theFace) ) return false; // bitmap font
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;
TT_HoriHeader *hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(theFace, ft_sfnt_hhea);
if (hhea == NULL) return false;
run = hhea->caret_Slope_Run;
return true;
}
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() ) {
{
int no=-1;
if ( id_to_no.find(glyph_id) == id_to_no.end() ) {
} else {
no=id_to_no[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)
}
Path* font_instance::Outline(int glyph_id,Path* copyInto)
return src_o;
}
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)
}
double font_instance::Advance(int glyph_id,bool vertical)
}
}
return 0;
}
}
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;
{
font_style nStyle;
nStyle.transform=trs;