Пример #1
0
  T42_Size_Request( FT_Size          t42size,      /* T42_Size */
                    FT_Size_Request  req )
  {
    T42_Size  size = (T42_Size)t42size;
    T42_Face  face = (T42_Face)t42size->face;
    FT_Error  error;


    FT_Activate_Size( size->ttsize );

    error = FT_Request_Size( face->ttf_face, req );
    if ( !error )
      t42size->metrics = face->ttf_face->size->metrics;

    return error;
  }
Пример #2
0
  T42_Size_Init( FT_Size  size )         /* T42_Size */
  {
    T42_Size  t42size = (T42_Size)size;
    FT_Face   face    = size->face;
    T42_Face  t42face = (T42_Face)face;
    FT_Size   ttsize;
    FT_Error  error;


    error = FT_New_Size( t42face->ttf_face, &ttsize );
    t42size->ttsize = ttsize;

    FT_Activate_Size( ttsize );

    return error;
  }
Пример #3
0
/*
 * Class:     sage_FreetypeFont
 * Method:    deriveFontFace0
 * Signature: (JI)J
 */
JNIEXPORT jlong JNICALL Java_sage_FreetypeFont_deriveFontFace0
  (JNIEnv *env, jobject jo, jlong fontPtr, jint ptSize, jint style)
{
	FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr;
	FT_Size newSize;
	int error = FT_New_Size(fontData->facePtr, &newSize);
	if (error)
	{
		sysOutPrint(env, "Error deriving freetype font of %d\r\n", error);
		return 0;
	}
	FT_Activate_Size(newSize);
	int scrnDPI = 72;//96;
	error = FT_Set_Char_Size(
            fontData->facePtr,    /* handle to face object           */
            0,       /* char_width in 1/64th of points  */
            (int)(ptSize*64 + 0.5f),   /* char_height in 1/64th of points */
            scrnDPI,     /* horizontal device resolution    */
            scrnDPI );   /* vertical device resolution      */
	if (error)
	{
		sysOutPrint(env, "Error setting freetype char size of %d\r\n", error);
		return 0;
	}

	FTDataStruct* rv = (FTDataStruct*)malloc(sizeof(FTDataStruct));
	rv->sizePtr = newSize;
	rv->facePtr = fontData->facePtr;
	rv->style = 0;
	// Remove styles already applied to the TTF itself
	if ((style & sage_FreetypeFont_BOLD) != 0)
	{
		if ((fontData->facePtr->style_flags & FT_STYLE_FLAG_BOLD) == 0)
		{
			rv->style = rv->style | FT_STYLE_FLAG_BOLD;
		}
	}
	if ((style & sage_FreetypeFont_ITALIC) != 0)
	{
		if ((fontData->facePtr->style_flags & FT_STYLE_FLAG_ITALIC) == 0)
		{
			rv->style = rv->style | FT_STYLE_FLAG_ITALIC;
		}
	}
	return (jlong)(intptr_t) rv;
}
Пример #4
0
  T42_Size_Select( FT_Size   t42size,         /* T42_Size */
                   FT_ULong  strike_index )
  {
    T42_Size  size = (T42_Size)t42size;
    T42_Face  face = (T42_Face)t42size->face;
    FT_Error  error;


    FT_Activate_Size( size->ttsize );

    error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
    if ( !error )
      t42size->metrics = face->ttf_face->size->metrics;

    return error;

  }
Пример #5
0
  T42_Size_SetChars( T42_Size    size,
                     FT_F26Dot6  char_width,
                     FT_F26Dot6  char_height,
                     FT_UInt     horz_resolution,
                     FT_UInt     vert_resolution )
  {
    FT_Face   face    = size->root.face;
    T42_Face  t42face = (T42_Face)face;


    FT_Activate_Size( size->ttsize );

    return FT_Set_Char_Size( t42face->ttf_face,
                             char_width,
                             char_height,
                             horz_resolution,
                             vert_resolution );
  }
Пример #6
0
/*
 * Class:     FreetypeFont
 * Method:    renderGlyph0
 * Signature: (JLjava/awt/image/BufferedImage;II)I
 */
JNIEXPORT jint JNICALL Java_sage_FreetypeFont_renderGlyph0
  (JNIEnv *env, jobject jo, jlong fontPtr, jobject buffImage, jint imageX, jint imageY)
{
	FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr;
	FT_Face face = fontData->facePtr;
	FT_Activate_Size(fontData->sizePtr);
	int error = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
	if (error)
		return error;
	static jmethodID biSetRGB = 0;
	static jmethodID biGetWidth = 0;
	static jmethodID biGetHeight = 0;
	if (!biSetRGB)
	{
		biSetRGB = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, buffImage), "setRGB", "(III)V");
		biGetWidth = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, buffImage), "getWidth", "()I");
		biGetHeight = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, buffImage), "getHeight", "()I");
	}
	int width = face->glyph->bitmap.width;
	int height = face->glyph->bitmap.rows;
	int x=0,y=0;
	imageX += face->glyph->bitmap_left;
	imageY -= face->glyph->bitmap_top;
//	imageY += (face->size->metrics.ascender >> 6);
	int biWidth = (*env)->CallIntMethod(env, buffImage, biGetWidth);
	int biHeight = (*env)->CallIntMethod(env, buffImage, biGetHeight);
	unsigned char* bufPtr = face->glyph->bitmap.buffer;
	for (;y < height; y++, bufPtr += face->glyph->bitmap.pitch)
	{
		if (imageY + y < 0 || imageY + y >= biHeight)
			continue;
		for (x = 0; x < width; x++)
		{
			if (imageX + x < 0 || imageX + x >= biWidth)
				continue;
			unsigned char bv = *(bufPtr + x);
			int color = (bv << 24) | (bv << 16) | (bv << 8) | bv;
			(*env)->CallVoidMethod(env, buffImage, biSetRGB, x + imageX, y + imageY, color);
		}
	}
	return 0;
}
Пример #7
0
  FTC_Manager_Lookup_Size( FTC_Manager  manager,
                           FTC_Font     font,
                           FT_Face     *aface,
                           FT_Size     *asize )
  {
    FT_Error  error;


    /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */
    if ( aface )
      *aface = 0;

    if ( asize )
      *asize = 0;

    error = FTC_Manager_Lookup_Face( manager, font->face_id, aface );
    if ( !error )
    {
      FTC_SizeQueryRec  query;
      FTC_SizeNode      node;


      query.face   = *aface;
      query.width  = font->pix_width;
      query.height = font->pix_height;

      error = FT_LruList_Lookup( manager->sizes_list,
                                 (FT_LruKey)&query,
                                 (FT_LruNode*)&node );
      if ( !error )
      {
        /* select the size as the current one for this face */
        FT_Activate_Size( node->size );

        if ( asize )
          *asize = node->size;
      }
    }

    return error;
  }
Пример #8
0
static int setupFTContext(JNIEnv *env,
                          jobject font2D,
                          FTScalerInfo *scalerInfo,
                          FTScalerContext *context) {
    int errCode = 0;

    scalerInfo->env = env;
    scalerInfo->font2D = font2D;

    if (context != NULL) {
        FT_Set_Transform(scalerInfo->face, &context->transform, NULL);

        errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);

        if (errCode == 0) {
            errCode = FT_Activate_Size(scalerInfo->face->size);
        }
    }

    return errCode;
}
Пример #9
0
  static FT_Error
  ftc_scaler_lookup_size( FTC_Manager  manager,
                          FTC_Scaler   scaler,
                          FT_Size     *asize )
  {
    FT_Face   face;
    FT_Size   size = NULL;
    FT_Error  error;


    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
    if ( error )
      goto Exit;

    error = FT_New_Size( face, &size );
    if ( error )
      goto Exit;

    FT_Activate_Size( size );

    if ( scaler->pixel )
      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
    else
      error = FT_Set_Char_Size( face,
                                (FT_F26Dot6)scaler->width,
                                (FT_F26Dot6)scaler->height,
                                scaler->x_res,
                                scaler->y_res );
    if ( error )
    {
      FT_Done_Size( size );
      size = NULL;
    }

  Exit:
    *asize = size;
    return error;
  }
Пример #10
0
  ftc_size_node_init( FTC_SizeNode   node,
                      FTC_SizeQuery  query )
  {
    FT_Face   face = query->face;
    FT_Size   size;
    FT_Error  error;


    node->size = NULL;
    error = FT_New_Size( face, &size );
    if ( !error )
    {
      FT_Activate_Size( size );
      error = FT_Set_Pixel_Sizes( query->face,
                                  query->width,
                                  query->height );
      if ( error )
        FT_Done_Size( size );
      else
        node->size = size;
    }
    return error;
  }
Пример #11
0
static Font_Info *
_font_slave_int_load(const Slave_Msg_Font_Load *msg, Font_Source_Info *fsi)
{
   int error;
   int val, dv;
   int ret;
   Font_Info *fi = calloc(1, sizeof(*fi));

   error = FT_New_Size(fsi->face, &(fi->size));
   if (!error)
     FT_Activate_Size(fi->size);

   fi->fsize = msg->size;
   fi->dpi = msg->dpi;
   fi->real_size = msg->size * 64;
   fi->fsi = fsi;
   error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi);
   if (error)
     error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);

   if (error)
     {
        int i, maxd = 0x7fffffff;
        int chosen_size = 0;
        int chosen_size2 = 0;

        for (i = 0; i < fsi->face->num_fixed_sizes; i++)
          {
             int s, cd;

             s = fsi->face->available_sizes[i].size;
             cd = chosen_size - fi->real_size;
             if (cd < 0) cd = -cd;
             if (cd < maxd)
               {
                  maxd = cd;
                  chosen_size = s;
                  chosen_size2 = fsi->face->available_sizes[i].y_ppem;
                  if (maxd == 0) break;
               }
          }
        fi->real_size = chosen_size;
        error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);

        if (error)
          {
             error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
             if (error)
               {
                  /* hack around broken fonts */
                  fi->real_size = (chosen_size2 / 64) * 60;
                  error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
                  if (error)
                    {
                       ERR("Could not choose the font size for font: '%s:%s'.",
                           msg->file, msg->name);
                       FT_Done_Size(fi->size);
                       free(fi);
                       return NULL;
                    }
               }
          }
     }

   fi->max_h = 0;
   val = (int)fsi->face->bbox.yMax;
   if (fsi->face->units_per_EM != 0)
     {
        dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
        ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
     }
   else ret = val;
   fi->max_h += ret;
   val = -(int)fsi->face->bbox.yMin;
   if (fsi->face->units_per_EM != 0)
     {
        dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
        ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
     }
   else ret = val;
   fi->max_h += ret;

   fi->runtime_rend = FONT_REND_REGULAR;
   if ((msg->rend_flags & FONT_REND_SLANT) &&
       !(fsi->face->style_flags & FT_STYLE_FLAG_ITALIC))
     fi->runtime_rend |= FONT_REND_SLANT;
   if ((msg->rend_flags & FONT_REND_WEIGHT) &&
       !(fsi->face->style_flags & FT_STYLE_FLAG_BOLD))
     fi->runtime_rend |= FONT_REND_WEIGHT;

   return fi;
}
Пример #12
0
EAPI Eina_Bool
evas_common_text_props_content_create(void *_fi, const Eina_Unicode *text,
      Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props,
      size_t par_pos, int len)
{
   RGBA_Font_Int *fi = (RGBA_Font_Int *) _fi;

   if (text_props->info)
     {
        evas_common_text_props_content_unref(text_props);
     }
   if (len == 0)
     {
        text_props->info = NULL;
        text_props->start = text_props->len = text_props->text_offset = 0;
     }
   text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));

   text_props->font_instance = fi;

   evas_common_font_int_reload(fi);
   if (fi->src->current_size != fi->size)
     {
        FTLOCK();
        FT_Activate_Size(fi->ft.size);
        FTUNLOCK();
        fi->src->current_size = fi->size;
     }

#ifdef OT_SUPPORT
   size_t char_index;
   Evas_Font_Glyph_Info *gl_itr;
   Evas_Coord pen_x = 0, adjust_x = 0;
   (void) par_props;
   (void) par_pos;

   evas_common_font_ot_populate_text_props(text, text_props, len);

   gl_itr = text_props->info->glyph;
   for (char_index = 0 ; char_index < text_props->len ; char_index++)
     {
        FT_UInt idx;
        RGBA_Font_Glyph *fg;
        Eina_Bool is_replacement = EINA_FALSE;
        /* If we got a malformed index, show the replacement char instead */
        if (gl_itr->index == 0)
          {
             gl_itr->index = evas_common_get_char_index(fi, REPLACEMENT_CHAR);
             is_replacement = EINA_TRUE;
          }
        idx = gl_itr->index;
        LKL(fi->ft_mutex);
        fg = evas_common_font_int_cache_glyph_get(fi, idx);
        if (!fg)
          {
             LKU(fi->ft_mutex);
             continue;
          }
        LKU(fi->ft_mutex);

        gl_itr->x_bear = fg->glyph_out->left;
        gl_itr->width = fg->glyph_out->bitmap.width;
        /* text_props->info->glyph[char_index].advance =
         * text_props->info->glyph[char_index].index =
         * already done by the ot function */
        if (EVAS_FONT_CHARACTER_IS_INVISIBLE(
              text[text_props->info->ot[char_index].source_cluster]))
          {
             gl_itr->index = 0;
             /* Reduce the current advance */
             if (gl_itr > text_props->info->glyph)
               {
                  adjust_x -= gl_itr->pen_after - (gl_itr - 1)->pen_after;
               }
             else
               {
                  adjust_x -= gl_itr->pen_after;
               }
          }
        else
          {
             if (is_replacement)
               {
                  /* Update the advance accordingly */
                  adjust_x += (pen_x + (fg->glyph->advance.x >> 16)) -
                     gl_itr->pen_after;
               }
             pen_x = gl_itr->pen_after;
          }
        gl_itr->pen_after += adjust_x;

        fi = text_props->font_instance;
        gl_itr++;
     }
#else
   /* We are walking the string in visual ordering */
   Evas_Font_Glyph_Info *gl_itr;
   Eina_Bool use_kerning;
   FT_UInt prev_index;
   FT_Face pface = NULL;
   Evas_Coord pen_x = 0;
   int adv_d, i;
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
   Eina_Unicode *base_str = NULL;
   if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
     {
        text = base_str = eina_unicode_strndup(text, len);
        evas_bidi_shape_string(base_str, par_props, par_pos, len);
     }
#else
   (void) par_props;
   (void) par_pos;
#endif

   FTLOCK();
   use_kerning = FT_HAS_KERNING(fi->src->ft.face);
   FTUNLOCK();
   prev_index = 0;

   i = len;
   text_props->info->glyph = calloc(len,
                                    sizeof(Evas_Font_Glyph_Info));

   if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
     {
        text += len - 1;
        adv_d = -1;
     }
   else
     {
        adv_d = 1;
     }

   gl_itr = text_props->info->glyph;
   for ( ; i > 0 ; gl_itr++, text += adv_d, i--)
     {
        FT_UInt idx;
        RGBA_Font_Glyph *fg;
        int _gl, kern;
        Evas_Coord adv;
        _gl = *text;
        if (_gl == 0) break;

        idx = evas_common_get_char_index(fi, _gl);
        if (idx == 0)
          {
             idx = evas_common_get_char_index(fi, REPLACEMENT_CHAR);
          }

        LKL(fi->ft_mutex);
        fg = evas_common_font_int_cache_glyph_get(fi, idx);
        if (!fg)
          {
             LKU(fi->ft_mutex);
             continue;
          }
        kern = 0;

        if ((use_kerning) && (prev_index) && (idx) &&
            (pface == fi->src->ft.face))
          {
             if (evas_common_font_query_kerning(fi, prev_index, idx, &kern))
               {
                  pen_x += kern;
                  (gl_itr - 1)->pen_after +=
                     EVAS_FONT_ROUND_26_6_TO_INT(kern);
               }
          }

        pface = fi->src->ft.face;
        LKU(fi->ft_mutex);

        gl_itr->index = idx;
        gl_itr->x_bear = fg->glyph_out->left;
        adv = fg->glyph->advance.x >> 10;
        gl_itr->width = fg->glyph_out->bitmap.width;

        if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
          {
             gl_itr->index = 0;
          }
        else
          {
             pen_x += adv;
          }

        gl_itr->pen_after = EVAS_FONT_ROUND_26_6_TO_INT(pen_x);

        prev_index = idx;
     }
   text_props->len = len;
# if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
   if (base_str)
      free(base_str);
# endif
#endif
   text_props->text_len = len;
   text_props->info->refcount = 1;
   return EINA_TRUE;
}
Пример #13
0
Font::TextSize Font::process(int x, int y, text_iterator start, text_iterator end, Color color) {
	
	FT_Activate_Size(m_size);
	
	Vec2f pen(x, y);
		
	int startX = 0;
	int endX = 0;
	
	if(DoDraw) {
		// Subtract one line height (since we flipped the Y origin to be like GDI)
		pen.y += m_size->metrics.ascender >> 6;
	}
	
	FT_UInt prevGlyphIndex = 0;
	FT_Pos prevRsbDelta = 0;
	
	std::vector< std::vector<TexturedVertex> > mapTextureVertices;
	
	for(text_iterator it = start; it != end; ) {
		
		// Get glyph in glyph map
		glyph_iterator itGlyph = getNextGlyph(it, end);
		if(itGlyph == m_glyphs.end()) {
			continue;
		}
		const Glyph & glyph = itGlyph->second;
		
		// Kerning
		if(FT_HAS_KERNING(m_size->face)) {
			if(prevGlyphIndex != 0) {
				FT_Vector delta;
				FT_Get_Kerning(m_size->face, prevGlyphIndex, glyph.index, FT_KERNING_DEFAULT, &delta);
				pen.x += delta.x >> 6;
			}
			prevGlyphIndex = glyph.index;
		}
		
		// Auto hinting adjustments
		if(prevRsbDelta - glyph.lsb_delta >= 32) {
			pen.x--;
		} else if(prevRsbDelta - glyph.lsb_delta < -32) {
			pen.x++;
		}
		prevRsbDelta = glyph.rsb_delta;
		
		// Draw
		if(DoDraw && glyph.size.x != 0 && glyph.size.y != 0) {
			if(glyph.texture >= mapTextureVertices.size()) {
				mapTextureVertices.resize(glyph.texture + 1);
			}
			addGlyphVertices(mapTextureVertices[glyph.texture], glyph, pen, color);
		} else {
			ARX_UNUSED(pen), ARX_UNUSED(color);
		}
		
		// If this is the first drawn char, note the start position
		if(startX == endX) {
			startX = glyph.draw_offset.x;
		}
		endX = s32(pen.x) + glyph.draw_offset.x + glyph.size.x;
		
		// Advance
		pen.x += glyph.advance.x;
	}
Пример #14
0
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
        : SkScalerContext(desc), fFTSize(NULL) {
    SkAutoMutexAcquire  ac(gFTMutex);

    FT_Error    err;

    if (gFTCount == 0) {
        err = FT_Init_FreeType(&gFTLibrary);
//        SkDEBUGF(("FT_Init_FreeType returned %d\n", err));
        SkASSERT(err == 0);
    }
    ++gFTCount;

    // load the font file
    fFaceRec = ref_ft_face(fRec.fFontID);
    fFace = fFaceRec ? fFaceRec->fFace : NULL;

    // compute our factors from the record

    SkMatrix    m;

    fRec.getSingleMatrix(&m);

#ifdef DUMP_STRIKE_CREATION
    SkString     keyString;
    SkFontHost::GetDescriptorKeyString(desc, &keyString);
    printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
           SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
           SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0][1]),
           SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1][1]),
           fRec.fHints, fRec.fMaskFormat, keyString.c_str());
#endif

    //  now compute our scale factors
    SkScalar    sx = m.getScaleX();
    SkScalar    sy = m.getScaleY();

    if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
        // sort of give up on hinting
        sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
        sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
        sx = sy = SkScalarAve(sx, sy);

        SkScalar inv = SkScalarInvert(sx);

        // flip the skew elements to go from our Y-down system to FreeType's
        fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
        fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
        fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
        fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
    } else {
        fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
        fMatrix22.xy = fMatrix22.yx = 0;
    }

    fScaleX = SkScalarToFixed(sx);
    fScaleY = SkScalarToFixed(sy);

    // compute the flags we send to Load_Glyph
    {
        uint32_t flags = FT_LOAD_DEFAULT;
        uint32_t render_flags = FT_LOAD_TARGET_NORMAL;

        // we force autohinting at the moment

        switch (fRec.fHints) {
        case kNo_Hints:
            flags |= FT_LOAD_NO_HINTING;
            break;
        case kSubpixel_Hints:
            flags |= FT_LOAD_FORCE_AUTOHINT;
            render_flags = FT_LOAD_TARGET_LIGHT;
            break;
        case kNormal_Hints:
            flags |= FT_LOAD_FORCE_AUTOHINT;
#ifdef ANDROID
            /*  Switch to light hinting (vertical only) to address some chars
                that behaved poorly with NORMAL. In the future we could consider
                making this choice exposed at runtime to the caller.
            */
            render_flags = FT_LOAD_TARGET_LIGHT;
#endif
            break;
        }

        if (SkMask::kBW_Format == fRec.fMaskFormat)
            render_flags = FT_LOAD_TARGET_MONO;
        else if (SkMask::kLCD_Format == fRec.fMaskFormat)
            render_flags = FT_LOAD_TARGET_LCD;

        fLoadGlyphFlags = flags | render_flags;
    }

    // now create the FT_Size

    {
        FT_Error    err;

        err = FT_New_Size(fFace, &fFTSize);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Size(0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFace = NULL;
            return;
        }

        err = FT_Activate_Size(fFTSize);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFTSize = NULL;
        }

        err = FT_Set_Char_Size( fFace,
                                SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY),
                                72, 72);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFace = NULL;
            return;
        }

        FT_Set_Transform( fFace, &fMatrix22, NULL);
    }
}
Пример #15
0
/*
 * Class:     sage_FreetypeFont
 * Method:    renderGlyphRaw0
 * Signature: (JLsage/media/image/RawImage;IIII)Lsage/media/image/RawImage;
 */
JNIEXPORT jobject JNICALL Java_sage_FreetypeFont_renderGlyphRaw0
  (JNIEnv *env, jobject jo, jlong fontPtr, jobject inRawImage, jint rawWidth, jint rawHeight, jint imageX, jint imageY)
{
	static jclass rawImageClass = 0;
	static jmethodID rawImageConstruct = 0;
	static jmethodID getDataMeth = 0;
	if (!rawImageClass)
	{
		rawImageClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "sage/media/image/RawImage"));
		if ((*env)->ExceptionOccurred(env))
		{
			return NULL;
		}
		rawImageConstruct = (*env)->GetMethodID(env, rawImageClass, "<init>", "(IILjava/nio/ByteBuffer;ZI)V");
		if ((*env)->ExceptionOccurred(env))
		{
			return NULL;
		}
		getDataMeth = (*env)->GetMethodID(env, rawImageClass, "getData", "()Ljava/nio/ByteBuffer;");
		if ((*env)->ExceptionOccurred(env))
		{
			return NULL;
		}
	}
	jobject rv = inRawImage;
	unsigned char* myImageData = NULL;
	if (!rv)
	{
		sysOutPrint(env, "Creating new RawImage for font rendering w=%d h=%d\r\n", rawWidth, rawHeight);
		// Create the RawImage object and the native buffer for it if it doesn't exist yet
		myImageData = (unsigned char*) calloc(4*rawWidth*rawHeight, 1);
		jobject dbuf = (*env)->NewDirectByteBuffer(env, (void*)myImageData, 4*rawWidth*rawHeight);
		if ((*env)->ExceptionOccurred(env))
		{
			free(myImageData);
			return NULL;
		}

		rv = (*env)->NewObject(env, rawImageClass, rawImageConstruct, rawWidth, rawHeight, 
			dbuf, JNI_TRUE, 4*rawWidth);
		if ((*env)->ExceptionOccurred(env))
		{
			free(myImageData);
			return NULL;
		}
	}
	else
	{
		// Get the address to the native image buffer so we can write to it
		jobject bb = (*env)->CallObjectMethod(env, rv, getDataMeth);
		if ((*env)->ExceptionOccurred(env))
		{
			return NULL;
		}
		myImageData = (unsigned char*) (*env)->GetDirectBufferAddress(env, bb);
	}

	FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr;
	FT_Face face = fontData->facePtr;
	FT_Activate_Size(fontData->sizePtr);
	// Render the glyph to a FT buffer
	int error = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
	if (error)
		return NULL;
	int width = face->glyph->bitmap.width;
	int height = face->glyph->bitmap.rows;
	int x=0,y=0;
	imageX += face->glyph->bitmap_left;
	imageY -= face->glyph->bitmap_top;
//	imageY += (face->size->metrics.ascender >> 6);
	unsigned char* bufPtr = face->glyph->bitmap.buffer;
	int yOff, off;
	// Copy the glyph to our image buffer
	for (;y < height; y++, bufPtr += face->glyph->bitmap.pitch)
	{
		if (imageY + y < 0 || imageY + y >= rawHeight)
			continue;
		yOff = (imageY + y)*rawWidth*4;
		for (x = 0; x < width; x++)
		{
			if (imageX + x < 0 || imageX + x >= rawWidth)
				continue;
			off = yOff + (imageX + x)*4;
			unsigned char bv = *(bufPtr + x);
			myImageData[off] = bv;
			myImageData[off + 1] = bv;
			myImageData[off + 2] = bv;
			myImageData[off + 3] = bv;
		}
	}
	return rv;
}
Пример #16
0
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
        : SkScalerContext(desc) {
    SkAutoMutexAcquire  ac(gFTMutex);

    if (gFTCount == 0) {
        if (!InitFreetype()) {
            sk_throw();
        }
    }
    ++gFTCount;

    // load the font file
    fFTSize = NULL;
    fFace = NULL;
    fFaceRec = ref_ft_face(fRec.fFontID);
    if (NULL == fFaceRec) {
        return;
    }
    fFace = fFaceRec->fFace;

    // compute our factors from the record

    SkMatrix    m;

    fRec.getSingleMatrix(&m);

#ifdef DUMP_STRIKE_CREATION
    SkString     keyString;
    SkFontHost::GetDescriptorKeyString(desc, &keyString);
    printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
           SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
           SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0][1]),
           SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1][1]),
           fRec.getHinting(), fRec.fMaskFormat, keyString.c_str());
#endif

    //  now compute our scale factors
    SkScalar    sx = m.getScaleX();
    SkScalar    sy = m.getScaleY();

    if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
        // sort of give up on hinting
        sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
        sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
        sx = sy = SkScalarAve(sx, sy);

        SkScalar inv = SkScalarInvert(sx);

        // flip the skew elements to go from our Y-down system to FreeType's
        fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
        fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
        fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
        fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
    } else {
        fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
        fMatrix22.xy = fMatrix22.yx = 0;
    }

    fScaleX = SkScalarToFixed(sx);
    fScaleY = SkScalarToFixed(sy);

    // compute the flags we send to Load_Glyph
    {
        FT_Int32 loadFlags = FT_LOAD_DEFAULT;

        if (SkMask::kBW_Format == fRec.fMaskFormat) {
            // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
            loadFlags = FT_LOAD_TARGET_MONO;
            if (fRec.getHinting() == SkPaint::kNo_Hinting)
                loadFlags = FT_LOAD_NO_HINTING;
        } else {
            switch (fRec.getHinting()) {
            case SkPaint::kNo_Hinting:
                loadFlags = FT_LOAD_NO_HINTING;
                break;
            case SkPaint::kSlight_Hinting:
                loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
                break;
            case SkPaint::kNormal_Hinting:
                loadFlags = FT_LOAD_TARGET_NORMAL;
                break;
            case SkPaint::kFull_Hinting:
                loadFlags = FT_LOAD_TARGET_NORMAL;
                if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat)
                    loadFlags = FT_LOAD_TARGET_LCD;
                else if (SkMask::kVerticalLCD_Format == fRec.fMaskFormat)
                    loadFlags = FT_LOAD_TARGET_LCD_V;
                break;
            default:
                SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
                break;
            }
        }

        if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0)
            loadFlags |= FT_LOAD_NO_BITMAP;

        fLoadGlyphFlags = loadFlags;
    }

    // now create the FT_Size

    {
        FT_Error    err;

        err = FT_New_Size(fFace, &fFTSize);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Size(0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFace = NULL;
            return;
        }

        err = FT_Activate_Size(fFTSize);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFTSize = NULL;
        }

        err = FT_Set_Char_Size( fFace,
                                SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY),
                                72, 72);
        if (err != 0) {
            SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
                        fFaceRec->fFontID, fScaleX, fScaleY, err));
            fFace = NULL;
            return;
        }

        FT_Set_Transform( fFace, &fMatrix22, NULL);
    }
}
Пример #17
0
/*
 * Class:     FreetypeFont
 * Method:    loadGlyph0
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL Java_sage_FreetypeFont_loadGlyph0
  (JNIEnv *env, jobject jo, jlong fontPtr, jint glyphCode)
{
	//FT_Face face = (FT_Face) facePtr;
	FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr;
	FT_Activate_Size(fontData->sizePtr);
	int error = FT_Load_Glyph(fontData->facePtr, glyphCode, FT_LOAD_FORCE_AUTOHINT);
	if ((fontData->style & FT_STYLE_FLAG_BOLD) != 0)
	{
		// Apply bold effect
		if (fontData->facePtr->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
		{
			/* some reasonable strength */
			FT_Pos strength = FT_MulFix(fontData->facePtr->units_per_EM,
				fontData->facePtr->size->metrics.y_scale ) / 42;

			FT_BBox bbox_before, bbox_after;
			// The bounding box code was what XBMC was using to do this calculation; but the
			// examples in the freetype library use the *4 math below which then doesn't clip
			// the text when we render it.
//			FT_Outline_Get_CBox(&fontData->facePtr->glyph->outline, &bbox_before);
			FT_Outline_Embolden(&fontData->facePtr->glyph->outline, strength);  // ignore error
//			FT_Outline_Get_CBox(&fontData->facePtr->glyph->outline, &bbox_after);

//			FT_Pos dx = bbox_after.xMax - bbox_before.xMax;
//			FT_Pos dy = bbox_after.yMax - bbox_before.yMax;
FT_Pos dx = strength * 4;
FT_Pos dy = dx;
			if (fontData->facePtr->glyph->advance.x)
				fontData->facePtr->glyph->advance.x += dx;

			if (fontData->facePtr->glyph->advance.y)
				fontData->facePtr->glyph->advance.y += dy;

			fontData->facePtr->glyph->metrics.width        += dx;
			fontData->facePtr->glyph->metrics.height       += dy;
			fontData->facePtr->glyph->metrics.horiBearingY += dy;
			fontData->facePtr->glyph->metrics.horiAdvance  += dx;
			fontData->facePtr->glyph->metrics.vertBearingX -= dx / 2;
			fontData->facePtr->glyph->metrics.vertBearingY += dy;
			fontData->facePtr->glyph->metrics.vertAdvance  += dy;
		}
	}
	if ((fontData->style & FT_STYLE_FLAG_ITALIC) != 0)
	{
		// Apply italics effect
		if (fontData->facePtr->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
		{
			/* For italic, simply apply a shear transform, with an angle */
			/* of about 12 degrees.                                      */

			FT_Matrix    transform;
			transform.xx = 0x10000L;
			transform.yx = 0x00000L;

			transform.xy = 0x06000L;
			transform.yy = 0x10000L;

			FT_BBox bbox_before, bbox_after;
			FT_Outline_Get_CBox(&fontData->facePtr->glyph->outline, &bbox_before);
			FT_Outline_Transform(&fontData->facePtr->glyph->outline, &transform);
			FT_Outline_Get_CBox(&fontData->facePtr->glyph->outline, &bbox_after);

			FT_Pos dx = bbox_after.xMax - bbox_before.xMax;
			FT_Pos dy = bbox_after.yMax - bbox_before.yMax;

			fontData->facePtr->glyph->metrics.width        += dx;
			fontData->facePtr->glyph->metrics.height       += dy;
		}
	}
}
Пример #18
0
Файл: font.cpp Проект: Greyze/xd
void xd::font::render(const std::string& text, const font_style& style,
	xd::shader_program::handle shader, const glm::mat4& mvp, glm::vec2 *pos)
{
	// check if we're rendering using this font or a linked font
	if (style.m_type && style.m_type->length() != 0) {
		font_map_t::iterator i = m_linked_fonts.find(*style.m_type);
		if (i == m_linked_fonts.end())
			throw invalid_font_type(*style.m_type);
		font_style linked_style = style;
		linked_style.m_type = boost::none;
		i->second->render(text, linked_style, shader, mvp, pos);
		return;
	}

	// check if the font size is already loaded
	auto it = m_face->sizes.find(style.m_size);
	if (it == m_face->sizes.end()) {
		// create a new size
		FT_Size size;
		if (FT_New_Size(m_face->handle, &size) != 0)
			throw font_load_failed(m_filename);
		// free the size in catch block if something goes wrong
		try {
			if (FT_Activate_Size(size) != 0)
				throw font_load_failed(m_filename);
			// set the pixel size
			if (FT_Set_Pixel_Sizes(m_face->handle, 0, style.m_size) != 0)
				throw font_load_failed(m_filename);
			// pre-load 7-bit ASCII glyphs
			for (int i = 0; i < 128; i++) {
				load_glyph(i, style.m_size);
			}
		} catch (...) {
			// free the size and re-throw
			FT_Done_Size(size);
			throw;
		}
		// insert the newly loaded size in the map
		m_face->sizes.insert(std::make_pair(style.m_size, size));
	} else {
		// activate the size
		FT_Activate_Size(it->second);
	}

	// bind to first texture unit
	glActiveTexture(GL_TEXTURE0);

	// setup the shader
	shader->use();
	shader->bind_uniform(m_mvp_uniform, mvp);
	shader->bind_uniform(m_color_uniform, style.m_color);
	shader->bind_uniform(m_texture_uniform, 0);

	// is kerning supported
	FT_Bool kerning = FT_HAS_KERNING(m_face->handle);

	// render each glyph in the string
	glm::vec2 text_pos;
	if (pos)
		text_pos = *pos;

	FT_UInt prev_glyph_index = 0;
	auto i = text.begin();
	while (i != text.end()) {
		// get the unicode code point
		utf8::uint32_t char_index = utf8::next(i, text.end());

		// get the cached glyph, or cache if it is not yet cached
		const detail::font::glyph& glyph = load_glyph(char_index, style.m_size);

		// bind the texture
		glBindTexture(GL_TEXTURE_2D, glyph.texture_id);

		// check for kerning
		if (kerning && glyph.glyph_index && prev_glyph_index) {
			FT_Vector kerning_delta;
			FT_Get_Kerning(m_face->handle, prev_glyph_index, glyph.glyph_index, FT_KERNING_DEFAULT, &kerning_delta);
			text_pos.x += kerning_delta.x >> 6;
		}

		// calculate exact offset
		glm::vec2 glyph_pos = text_pos;
		glyph_pos.x += glyph.offset.x;
		glyph_pos.y += glyph.offset.y;

		// add optional letter spacing
		glyph_pos.x += style.m_letter_spacing/2;

		// if shadow is enabled, draw the shadow first
		if (style.m_shadow) {
			// calculate shadow position
			glm::vec2 shadow_pos = glyph_pos;
			shadow_pos.x += style.m_shadow->x;
			shadow_pos.y += style.m_shadow->y;

			// calculate shadow color
			glm::vec4 shadow_color = style.m_shadow->color;
			shadow_color.a *= style.m_color.a;

			// bind uniforms
			shader->bind_uniform(m_color_uniform, shadow_color);
			shader->bind_uniform(m_position_uniform, shadow_pos);

			// draw shadow
			glyph.quad_ptr->render();

			// restore the text color
			shader->bind_uniform(m_color_uniform, style.m_color);
		}
		
		// if outline is enabled, draw outline
		if (style.m_outline) {
			// calculate outline color
			glm::vec4 outline_color = style.m_outline->color;
			outline_color.a *= style.m_color.a;

			// bind color
			shader->bind_uniform(m_color_uniform, outline_color);

			// draw font multiple times times to draw outline (EXPENSIVE!)
			for (int x = -style.m_outline->width; x <= style.m_outline->width; x++) {
				for (int y = -style.m_outline->width; y <= style.m_outline->width; y++) {
					if (x == 0 && y == 0)
						continue;
					shader->bind_uniform(m_position_uniform, glyph_pos + glm::vec2(x, y));
					glyph.quad_ptr->render();
				}
			}

			// restore the text color
			shader->bind_uniform(m_color_uniform, style.m_color);
		}

		// bind uniforms
		shader->bind_uniform(m_position_uniform, glyph_pos);

		// draw the glyph
		glyph.quad_ptr->render();
		
		// advance the position
		text_pos += glyph.advance;
		text_pos.x += style.m_letter_spacing;

		// keep track of previous glyph to do kerning
		prev_glyph_index = glyph.glyph_index;
	}