int renderTruetypeSymbolCairo(imageObj *img, double x, double y, symbolObj *symbol,
                              symbolStyleObj *s)
{
  int unicode;
  cairo_glyph_t glyph;
  cairo_text_extents_t extents;

  cairo_matrix_t trans;
  double ox,oy;
  cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img);
  cairo_renderer *r = CAIRO_RENDERER(img);
  faceCacheObj *face = getFontFace(cache,symbol->full_font_path);

  if(!face) return MS_FAILURE;

  cairo_save(r->cr);
  cairo_set_font_face(r->cr,face->face);
  cairo_set_font_size(r->cr,s->scale*96/72.0);


  msUTF8ToUniChar(symbol->character, &unicode);

  if (face->ftface->charmap &&
    face->ftface->charmap->encoding == FT_ENCODING_MS_SYMBOL)
    unicode |= 0xf000;

  glyph.index = FT_Get_Char_Index(face->ftface, unicode);
  glyph.x=0;
  glyph.y=0;
  cairo_glyph_extents(r->cr,&glyph,1,&extents);
  ox=extents.x_bearing+extents.width/2.;
  oy=extents.y_bearing+extents.height/2.;



  cairo_matrix_init_rotate(&trans,-s->rotation);

  cairo_matrix_transform_point(&trans,&ox,&oy);
  /* cairo_translate(cr,-extents.width/2,-extents.height/2); */

  cairo_translate(r->cr,x-ox,y-oy);
  cairo_rotate(r->cr, -s->rotation);

  cairo_glyph_path(r->cr,&glyph,1);

  if (s->outlinewidth) {
    msCairoSetSourceColor(r->cr, s->outlinecolor);
    cairo_set_line_width(r->cr, s->outlinewidth + 1);
    cairo_stroke_preserve(r->cr);
  }
  if(s->color) {
    msCairoSetSourceColor(r->cr, s->color);
    cairo_fill_preserve(r->cr);
  }
  cairo_new_path(r->cr);
  cairo_restore(r->cr);
  return MS_SUCCESS;
}
FontRanges CSSFontSelector::fontRangesForFamily(const FontDescription& fontDescription, const AtomicString& familyName)
{
    // FIXME: The spec (and Firefox) says user specified generic families (sans-serif etc.) should be resolved before the @font-face lookup too.
    bool resolveGenericFamilyFirst = familyName == standardFamily;

    AtomicString familyForLookup = resolveGenericFamilyFirst ? resolveGenericFamily(m_document, fontDescription, familyName) : familyName;
    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyForLookup);
    if (!face) {
        if (!resolveGenericFamilyFirst)
            familyForLookup = resolveGenericFamily(m_document, fontDescription, familyName);
        return FontRanges(FontCache::singleton().fontForFamily(fontDescription, familyForLookup));
    }

    return face->fontRanges(fontDescription);
}
Beispiel #3
0
Vector<std::reference_wrapper<CSSFontFace>> CSSFontFaceSet::matchingFaces(const String& font, const String&, ExceptionCode& ec)
{
    Vector<std::reference_wrapper<CSSFontFace>> result;
    Ref<MutableStyleProperties> style = MutableStyleProperties::create();
    auto parseResult = CSSParser::parseValue(style.ptr(), CSSPropertyFont, font, true, CSSStrictMode, nullptr);
    if (parseResult == CSSParser::ParseResult::Error) {
        ec = SYNTAX_ERR;
        return result;
    }

    FontTraitsMask fontTraitsMask;
    if (auto maskOptional = computeFontTraitsMask(style.get()))
        fontTraitsMask = maskOptional.value();
    else {
        ec = SYNTAX_ERR;
        return result;
    }

    RefPtr<CSSValue> family = style->getPropertyCSSValue(CSSPropertyFontFamily);
    if (!is<CSSValueList>(family.get())) {
        ec = SYNTAX_ERR;
        return result;
    }
    CSSValueList& familyList = downcast<CSSValueList>(*family);

    HashSet<AtomicString> uniqueFamilies;
    for (auto& family : familyList) {
        const CSSPrimitiveValue& primitive = downcast<CSSPrimitiveValue>(family.get());
        if (!primitive.isFontFamily())
            continue;
        uniqueFamilies.add(primitive.fontFamily().familyName);
    }

    for (auto& family : uniqueFamilies) {
        CSSSegmentedFontFace* faces = getFontFace(fontTraitsMask, family);
        if (!faces)
            continue;
        for (auto& constituentFace : faces->constituentFaces())
            result.append(constituentFace.get());
    }

    return result;
}
PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName)
{
    if (m_fontFaces.isEmpty()) {
        if (familyName.startsWith("-webkit-"))
            return fontDataForGenericFamily(m_document, fontDescription, familyName);
        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
            return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard");
        return 0;
    }

    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyName);
    // If no face was found, then return 0 and let the OS come up with its best match for the name.
    if (!face) {
        // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
        // settings.
        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
            return fontDataForGenericFamily(m_document, fontDescription, "-webkit-standard");
        return fontDataForGenericFamily(m_document, fontDescription, familyName);
    }

    // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
    return face->getFontData(fontDescription);
}
void CSSFontSelector::willUseFontData(const FontDescription& fontDescription, const AtomicString& family)
{
    CSSSegmentedFontFace* face = getFontFace(fontDescription, family);
    if (face)
        face->willUseFontData(fontDescription);
}
Beispiel #6
0
int renderGlyphsCairo(imageObj *img,double x, double y, labelStyleObj *style, char *text) {
    cairo_renderer *r = CAIRO_RENDERER(img);
    cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img);
    faceCacheObj *face = getFontFace(cache,style->font);

    char *utfptr=text;
    int i,has_kerning,unicode;
    unsigned long previdx=0;
    int numglyphs = msGetNumGlyphs(text);
    cairo_glyph_t glyph;
    cairo_text_extents_t extents;
    double px=0,py=0;

    if(face == NULL) {
        return MS_FAILURE;
    }

    cairo_set_font_face(r->cr,face->face);
    cairo_set_font_size(r->cr,style->size*96/72.0);

    cairo_save(r->cr);
    cairo_translate(r->cr,MS_NINT(x),MS_NINT(y));
    if(style->rotation != 0.0)
       cairo_rotate(r->cr, -style->rotation);

    has_kerning = FT_HAS_KERNING((face->ftface));
    for(i=0;i<numglyphs;i++) {
        utfptr+=msUTF8ToUniChar(utfptr, &unicode);
        glyph.x=px;
        glyph.y=py;
        if(unicode=='\n') {
            py += ceil(style->size*CAIROLINESPACE);
            px = 0;
            previdx=0;
            continue;
        }
        glyph.index = FT_Get_Char_Index(face->ftface, unicode);
        if( has_kerning && previdx ) {
            FT_Vector delta;
            FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
            px += delta.x / 64.;
        }
        cairo_glyph_extents(r->cr,&glyph,1,&extents);
        cairo_glyph_path(r->cr,&glyph,1);
        px += extents.x_advance;
        previdx=glyph.index;
    }

    if (style->outlinewidth > 0) {
        cairo_save(r->cr);
        msCairoSetSourceColor(r->cr, style->outlinecolor);
        cairo_set_line_width(r->cr, style->outlinewidth + 1);
        cairo_stroke_preserve(r->cr);
        cairo_restore(r->cr);
    }
    if(style->color) {
        msCairoSetSourceColor(r->cr, style->color);
        cairo_fill(r->cr);
    }
    cairo_new_path(r->cr);
    cairo_restore(r->cr);
    return MS_SUCCESS;
}
Beispiel #7
0
int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char *font, double size, char *text, rectObj *rect, double **advances) {
    
    
    cairoCacheData *cache = MS_RENDERER_CACHE(renderer);
    faceCacheObj *face = getFontFace(cache,font);
 
    char *utfptr=text;
    int i,has_kerning,unicode;
    unsigned long previdx=0;
    int numglyphs = msGetNumGlyphs(text);
    cairo_glyph_t glyph;
    cairo_text_extents_t extents;
    double px=0,py=0;

    if(face == NULL) {
        return MS_FAILURE;
    }

    cairo_set_font_face(cache->dummycr,face->face);
    cairo_set_font_size(cache->dummycr,size*96/72.0);

    has_kerning = FT_HAS_KERNING((face->ftface));

    if(advances != NULL) {
        *advances = (double*)malloc(numglyphs*sizeof(double));
    }

    for(i=0;i<numglyphs;i++) {
        utfptr+=msUTF8ToUniChar(utfptr, &unicode);
        glyph.x=px;
        glyph.y=py;
        if(unicode=='\n') {
            py += ceil(size*CAIROLINESPACE);
            px = 0;
            previdx=0;
            continue;
        }
        glyph.index = FT_Get_Char_Index(face->ftface, unicode);
        if( has_kerning && previdx ) {
            FT_Vector delta;
            FT_Get_Kerning( face->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
            px += delta.x / 64.;
        }
        cairo_glyph_extents(cache->dummycr,&glyph,1,&extents);
        
        if(i==0) {
            rect->minx = px+extents.x_bearing;
            rect->miny = py+extents.y_bearing;
            rect->maxx = px+extents.x_bearing+extents.width;
            rect->maxy = py+extents.y_bearing+extents.height;
        } else {
            rect->minx = MS_MIN(rect->minx,px+extents.x_bearing);
            rect->miny = MS_MIN(rect->miny,py+extents.y_bearing);
            rect->maxy = MS_MAX(rect->maxy,py+extents.y_bearing+extents.height);
            rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width);
        }
        if(advances!=NULL)
            (*advances)[i]=extents.x_advance;
        px += extents.x_advance;
        previdx=glyph.index;
    }
    /*
    rect->minx = 0;
    rect->miny = 0;
    rect->maxx = 1;
    rect->maxy = 1;
    */
    return MS_SUCCESS;
}
int getTruetypeTextBBoxCairo(rendererVTableObj *renderer, char **fonts, int numfonts, double size,
                             char *text, rectObj *rect, double **advances, int bAdjustBaseline)
{
  cairoCacheData *cache = MS_RENDERER_CACHE(renderer);
  faceCacheObj* face = getFontFace(cache,fonts[0]);

  int curfontidx = 0;
  char *utfptr=text;
  int i,unicode;
  unsigned long previdx=0;
  faceCacheObj* prevface = face;
  int numglyphs = msGetNumGlyphs(text);
  cairo_glyph_t glyph;
  cairo_text_extents_t extents;
  double px=0,py=0;

  if(face == NULL) {
    return MS_FAILURE;
  }

  cairo_set_font_face(cache->dummycr,face->face);
  cairo_set_font_size(cache->dummycr,size*96/72.0);

  if(advances != NULL) {
    *advances = (double*)malloc(numglyphs*sizeof(double));
  }

  for(i=0; i<numglyphs; i++) {
    utfptr+=msUTF8ToUniChar(utfptr, &unicode);
    glyph.x=px;
    glyph.y=py;
    if(unicode=='\n') {
      py += ceil(size*CAIROLINESPACE);
      px = 0;
      previdx=0;
      continue;
    }

    if (curfontidx != 0) {
      face = getFontFace(cache, fonts[0]);
      cairo_set_font_face(cache->dummycr, face->face);
      curfontidx = 0;
    }

    if (face->ftface->charmap &&
      face->ftface->charmap->encoding == FT_ENCODING_MS_SYMBOL)
      unicode |= 0xf000;

    glyph.index = FT_Get_Char_Index(face->ftface, unicode);

    if (glyph.index == 0) {
      int j;
      for (j = 1; j < numfonts; j++) {
        curfontidx = j;
        face = getFontFace(cache, fonts[j]);
        glyph.index = FT_Get_Char_Index(face->ftface, unicode);
        if (glyph.index != 0) {
          cairo_set_font_face(cache->dummycr, face->face);
          break;
        }
      }
    }

    if( FT_HAS_KERNING((prevface->ftface)) && previdx ) {
      FT_Vector delta;
      FT_Get_Kerning( prevface->ftface, previdx, glyph.index, FT_KERNING_DEFAULT, &delta );
      px += delta.x / 64.;
    }
    cairo_glyph_extents(cache->dummycr,&glyph,1,&extents);

    if(i==0) {
      rect->minx = px+extents.x_bearing;
      rect->miny = py+extents.y_bearing;
      rect->maxx = px+extents.x_bearing+extents.width;
      rect->maxy = py+(bAdjustBaseline?1:(extents.y_bearing+extents.height));
    } else {
      rect->minx = MS_MIN(rect->minx,px+extents.x_bearing);
      rect->miny = MS_MIN(rect->miny,py+extents.y_bearing);
      rect->maxy = MS_MAX(rect->maxy,py+(bAdjustBaseline?1:(extents.y_bearing+extents.height)));
      rect->maxx = MS_MAX(rect->maxx,px+extents.x_bearing+extents.width);
    }
    if(advances!=NULL)
      (*advances)[i]=extents.x_advance;
    px += extents.x_advance;
    previdx=glyph.index;
    prevface = face;
  }
  return MS_SUCCESS;
}