727 lines
23 KiB
C++
727 lines
23 KiB
C++
/**********************************************************************
|
|
|
|
Filename : GFxFontProviderPS3.cpp
|
|
Content : FreeType2 font provider
|
|
Created : 6/21/2007
|
|
Authors : Maxim Shemanarev
|
|
|
|
Copyright : (c) 2001-2007 Scaleform Corp. All Rights Reserved.
|
|
|
|
Notes :
|
|
|
|
Licensees may use this file in accordance with the valid Scaleform
|
|
Commercial License Agreement provided with the software.
|
|
|
|
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
|
|
THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR ANY PURPOSE.
|
|
|
|
----------------------------------------------------------------------
|
|
The code of these classes was taken from the Anti-Grain Geometry
|
|
Project and modified for the use by Scaleform.
|
|
Permission to use without restrictions is hereby granted to
|
|
Scaleform Corporation by the author of Anti-Grain Geometry Project.
|
|
See http://antigtain.com for details.
|
|
**********************************************************************/
|
|
|
|
#include <cell/sysmodule.h>
|
|
#include "GFxFontProviderPS3.h"
|
|
#include "GFxString.h"
|
|
#include "GFxShape.h"
|
|
#include "GMath2D.h"
|
|
|
|
#define PS3_CURVE_TAG(flag) (flag & 3)
|
|
#define PS3_CURVE_TAG_ON 1
|
|
#define PS3_CURVE_TAG_CONIC 0
|
|
#define PS3_CURVE_TAG_CUBIC 2
|
|
|
|
//------------------------------------------------------------------------
|
|
bool GFxExternalFontPS3::decomposeGlyphOutline(const CellFontGlyph* glyph,
|
|
GFxShapeNoStyles* shape)
|
|
{
|
|
struct PointType { float x, y; };
|
|
const CellFontGlyphOutline& outline = glyph->Outline;
|
|
PointType v_last;
|
|
PointType v_control;
|
|
PointType v_start;
|
|
|
|
GFxPathPacker path;
|
|
Float ratio = (shape->GetHintedGlyphSize() > 0) ? 20.0f : 1.0f;
|
|
|
|
const PointType* point;
|
|
const PointType* limit;
|
|
const uint8_t* tags;
|
|
|
|
int n; // index of contour in outline
|
|
int first = 0; // index of first point in contour
|
|
char tag; // current point's state
|
|
bool shapeValid = false;
|
|
|
|
for(n = 0; n < outline.contoursCount; n++)
|
|
{
|
|
int last; // index of last point in contour
|
|
|
|
last = outline.contourIndexs[n];
|
|
limit = (const PointType*)outline.Points + last;
|
|
|
|
v_start.x = outline.Points[first].x;
|
|
v_start.y = outline.Points[first].y;
|
|
v_last.x = outline.Points[last].x;
|
|
v_last.y = outline.Points[last].y;
|
|
|
|
v_control = v_start;
|
|
|
|
point = (const PointType*)outline.Points + first;
|
|
tags = outline.pointTags + first;
|
|
tag = PS3_CURVE_TAG(tags[0]);
|
|
|
|
// A contour cannot start with a cubic control point!
|
|
if(tag == PS3_CURVE_TAG_CUBIC) return false;
|
|
|
|
// check first point to determine origin
|
|
if( tag == PS3_CURVE_TAG_CONIC)
|
|
{
|
|
// first point is conic control. Yes, this happens.
|
|
if(PS3_CURVE_TAG(outline.pointTags[last]) == PS3_CURVE_TAG_ON)
|
|
{
|
|
// start at last point if it is on the curve
|
|
v_start = v_last;
|
|
limit--;
|
|
}
|
|
else
|
|
{
|
|
// if both first and last points are conic,
|
|
// start at their middle and record its position
|
|
// for closure
|
|
v_start.x = (v_start.x + v_last.x) / 2;
|
|
v_start.y = (v_start.y + v_last.y) / 2;
|
|
v_last = v_start;
|
|
}
|
|
point--;
|
|
tags--;
|
|
}
|
|
|
|
path.Reset();
|
|
path.SetFill0(1);
|
|
path.SetFill1(0);
|
|
path.SetMoveTo(SInt(ratio * v_start.x), -SInt(ratio * v_start.y));
|
|
|
|
while(point < limit)
|
|
{
|
|
point++;
|
|
tags++;
|
|
|
|
tag = PS3_CURVE_TAG(tags[0]);
|
|
switch(tag)
|
|
{
|
|
case PS3_CURVE_TAG_ON: // emit a single line_to
|
|
{
|
|
path.LineToAbs(SInt(ratio * point->x), -SInt(ratio * point->y));
|
|
continue;
|
|
}
|
|
|
|
case PS3_CURVE_TAG_CONIC: // consume conic arcs
|
|
{
|
|
v_control.x = point->x;
|
|
v_control.y = point->y;
|
|
|
|
Do_Conic:
|
|
if(point < limit)
|
|
{
|
|
PointType vec;
|
|
PointType v_middle;
|
|
|
|
point++;
|
|
tags++;
|
|
tag = PS3_CURVE_TAG(tags[0]);
|
|
|
|
vec.x = point->x;
|
|
vec.y = point->y;
|
|
|
|
if(tag == PS3_CURVE_TAG_ON)
|
|
{
|
|
path.CurveToAbs(SInt(ratio * v_control.x), -SInt(ratio * v_control.y),
|
|
SInt(ratio * vec.x), -SInt(ratio * vec.y));
|
|
continue;
|
|
}
|
|
|
|
if(tag != PS3_CURVE_TAG_CONIC) return false;
|
|
|
|
v_middle.x = (v_control.x + vec.x) / 2;
|
|
v_middle.y = (v_control.y + vec.y) / 2;
|
|
path.CurveToAbs(SInt(ratio * v_control.x), -SInt(ratio * v_control.y),
|
|
SInt(ratio * v_middle.x), -SInt(ratio * v_middle.y));
|
|
v_control = vec;
|
|
goto Do_Conic;
|
|
}
|
|
path.CurveToAbs(SInt(ratio * v_control.x), -SInt(ratio * v_control.y),
|
|
SInt(ratio * v_start.x), -SInt(ratio * v_start.y));
|
|
goto Close;
|
|
}
|
|
|
|
default: // PS3_CURVE_TAG_CUBIC
|
|
{
|
|
PointType vec1, vec2;
|
|
if(point + 1 > limit || PS3_CURVE_TAG(tags[1]) != PS3_CURVE_TAG_CUBIC)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
vec1 = point[0];
|
|
vec2 = point[1];
|
|
|
|
point += 2;
|
|
tags += 2;
|
|
|
|
if(point <= limit)
|
|
{
|
|
PointType vec;
|
|
vec = *point;
|
|
path.CurveToAbs(SInt(ratio * (vec1.x + vec2.x) / 2),
|
|
-SInt(ratio * (vec1.y + vec2.y) / 2),
|
|
SInt(ratio * vec.x), -SInt(ratio * vec.y));
|
|
continue;
|
|
}
|
|
path.CurveToAbs(SInt(ratio * (vec1.x + vec2.x) / 2),
|
|
-SInt(ratio * (vec1.y + vec2.y) / 2),
|
|
SInt(ratio * v_start.x), -SInt(ratio * v_start.y));
|
|
goto Close;
|
|
}
|
|
}
|
|
}
|
|
|
|
Close:
|
|
if (!path.IsEmpty())
|
|
{
|
|
path.ClosePath();
|
|
shape->AddPath(&path);
|
|
shapeValid = true;
|
|
}
|
|
first = last + 1;
|
|
}
|
|
return shapeValid;
|
|
}
|
|
|
|
/*
|
|
//------------------------------------------------------------------------
|
|
class GFxBitsetIterator
|
|
{
|
|
public:
|
|
GFxBitsetIterator(const UByte* bits, unsigned offset = 0) :
|
|
Bits(bits + (offset >> 3)),
|
|
Mask(UByte(0x80 >> (offset & 7)))
|
|
{}
|
|
|
|
void operator ++ ()
|
|
{
|
|
Mask >>= 1;
|
|
if(Mask == 0)
|
|
{
|
|
++Bits;
|
|
Mask = 0x80;
|
|
}
|
|
}
|
|
|
|
unsigned GetBit() const
|
|
{
|
|
return (*Bits) & Mask;
|
|
}
|
|
|
|
private:
|
|
const UByte* Bits;
|
|
UByte Mask;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxExternalFontPS3::decomposeGlyphBitmap(const FT_Bitmap& bitmap,
|
|
int x, int y,
|
|
GFxGlyphRaster* raster)
|
|
{
|
|
raster->Width = bitmap.width;
|
|
raster->Height = bitmap.rows;
|
|
raster->OriginX = -x;
|
|
raster->OriginY = y;
|
|
raster->Raster.resize(raster->Width * raster->Height);
|
|
|
|
int i;
|
|
int pitch = bitmap.pitch;
|
|
|
|
const UByte* src = (const UByte*)bitmap.buffer;
|
|
UByte* dst = &raster->Raster[0];
|
|
for(i = 0; i < bitmap.rows; i++)
|
|
{
|
|
GFxBitsetIterator bits(src, 0);
|
|
int j;
|
|
for(j = 0; j < bitmap.width; j++)
|
|
{
|
|
*dst++ = bits.GetBit() ? 255 : 0;
|
|
++bits;
|
|
}
|
|
src += pitch;
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxExternalFontPS3::~GFxExternalFontPS3()
|
|
{
|
|
if (FontOK == CELL_OK)
|
|
cellFontCloseFont(&Font);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxExternalFontPS3::GFxExternalFontPS3(GFxFontProviderPS3* pprovider,
|
|
const CellFontLibrary* library,
|
|
GFxFontInfoPS3* fontInfo) :
|
|
GFxFont(fontInfo->FontFlags),
|
|
pFontProvider(pprovider),
|
|
Name(fontInfo->FontName),
|
|
LastFontHeight(FontHeight),
|
|
RasterHintingRange(fontInfo->RasterHintingRange),
|
|
VectorHintingRange(fontInfo->VectorHintingRange),
|
|
MaxRasterHintedSize(fontInfo->MaxRasterHintedSize),
|
|
MaxVectorHintedSize(fontInfo->MaxVectorHintedSize),
|
|
FontOK(-1)
|
|
{
|
|
if (fontInfo->FontData)
|
|
{
|
|
FontOK = cellFontOpenFontMemory(
|
|
library,
|
|
(void*)fontInfo->FontData,
|
|
fontInfo->FontDataSize,
|
|
fontInfo->SubNum,
|
|
fontInfo->UniqueId,
|
|
&Font);
|
|
}
|
|
else
|
|
if (!fontInfo->FileName.IsEmpty())
|
|
{
|
|
FontOK = cellFontOpenFontFile(
|
|
library,
|
|
(uint8_t*)(fontInfo->FileName.ToCStr()),
|
|
fontInfo->SubNum,
|
|
fontInfo->UniqueId,
|
|
&Font);
|
|
}
|
|
else
|
|
{
|
|
FontOK = cellFontOpenFontset(library, &fontInfo->Type, &Font);
|
|
}
|
|
|
|
if(FontOK == CELL_OK)
|
|
setFontMetrics();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxExternalFontPS3::setFontMetrics()
|
|
{
|
|
cellFontSetScalePixel(&Font, FontHeight, FontHeight);
|
|
LastFontHeight = FontHeight;
|
|
|
|
CellFontHorizontalLayout layout;
|
|
cellFontGetHorizontalLayout(&Font, &layout);
|
|
SetFontMetrics(0, layout.baseLineY, layout.lineHeight-layout.baseLineY);
|
|
|
|
// Float ascent = Float(Face->ascender) * FontHeight / Face->units_per_EM;
|
|
// Float descent = -Float(Face->descender) * FontHeight / Face->units_per_EM;
|
|
// Float height = Float(Face->height) * FontHeight / Face->units_per_EM;
|
|
// SetFontMetrics(height - ascent + descent, ascent, descent);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
int GFxExternalFontPS3::GetGlyphIndex(UInt16 code) const
|
|
{
|
|
if (FontOK == CELL_OK)
|
|
{
|
|
const UInt* indexPtr = CodeTable.Get(code);
|
|
if (indexPtr)
|
|
return *indexPtr;
|
|
|
|
GFxExternalFontPS3* pthis = const_cast<GFxExternalFontPS3*>(this);
|
|
if (LastFontHeight != FontHeight)
|
|
{
|
|
// cellFontSetScalePixel is expensive. Avoid calling it often.
|
|
cellFontSetScalePixel(&pthis->Font, FontHeight, FontHeight);
|
|
pthis->LastFontHeight = FontHeight;
|
|
}
|
|
CellFontGlyphMetrics metrics;
|
|
int err = cellFontGetCharGlyphMetrics(&pthis->Font, code, &metrics);
|
|
if (err != CELL_OK)
|
|
return -1;
|
|
|
|
GlyphType glyph;
|
|
glyph.Code = code;
|
|
glyph.Advance = metrics.Horizontal.advance;
|
|
glyph.Bounds.Left = metrics.Horizontal.bearingX;
|
|
glyph.Bounds.Top = -metrics.Horizontal.bearingY;
|
|
glyph.Bounds.Right = glyph.Bounds.Left + metrics.width;
|
|
glyph.Bounds.Bottom = glyph.Bounds.Top + metrics.height;
|
|
|
|
// glyph.Bounds.Left = Float(Face->glyph->metrics.horiBearingX >> 6);
|
|
// glyph.Bounds.Top = -Float(Face->glyph->metrics.horiBearingY >> 6);
|
|
// glyph.Bounds.Right = Float(Face->glyph->metrics.width >> 6) + glyph.Bounds.Left;
|
|
// glyph.Bounds.Bottom = Float(Face->glyph->metrics.height >> 6) + glyph.Bounds.Top;
|
|
|
|
pthis->Glyphs.PushBack(glyph);
|
|
pthis->CodeTable.Add(code, (UInt)Glyphs.GetSize()-1);
|
|
return (UInt)Glyphs.GetSize()-1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
bool GFxExternalFontPS3::IsHintedVectorGlyph(UInt glyphIndex, UInt glyphSize) const
|
|
{
|
|
if (glyphIndex == (UInt)-1 ||
|
|
glyphSize > MaxVectorHintedSize ||
|
|
VectorHintingRange == DontHint)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (VectorHintingRange == HintAll)
|
|
return true;
|
|
|
|
return IsCJK(UInt16(Glyphs[glyphIndex].Code));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
bool GFxExternalFontPS3::IsHintedRasterGlyph(UInt glyphIndex, UInt glyphSize) const
|
|
{
|
|
if (glyphIndex == (UInt)-1 ||
|
|
glyphSize > MaxRasterHintedSize ||
|
|
RasterHintingRange == DontHint)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (VectorHintingRange == HintAll)
|
|
return true;
|
|
|
|
return IsCJK(UInt16(Glyphs[glyphIndex].Code));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxShapeBase* GFxExternalFontPS3::GetGlyphShape(UInt glyphIndex, UInt glyphSize)
|
|
{
|
|
if (glyphIndex == (UInt)-1)
|
|
return 0;
|
|
|
|
if (!IsHintedVectorGlyph(glyphIndex, glyphSize))
|
|
glyphSize = 0;
|
|
|
|
UInt pixelSize = glyphSize ? glyphSize : FontHeight;
|
|
|
|
if (LastFontHeight != pixelSize)
|
|
{
|
|
// cellFontSetScalePixel is expensive. Avoid calling it often.
|
|
cellFontSetScalePixel(&Font, (float)pixelSize, (float)pixelSize);
|
|
LastFontHeight = pixelSize;
|
|
}
|
|
|
|
CellFontGlyph *glyph;
|
|
int err = cellFontGenerateCharGlyph(&Font, Glyphs[glyphIndex].Code, &glyph);
|
|
if (err)
|
|
return 0;
|
|
|
|
GFxShapeNoStyles* pshape = new GFxShapeNoStyles(ShapePageSize);
|
|
pshape->SetHintedGlyphSize(glyphSize);
|
|
if(!decomposeGlyphOutline(glyph, pshape))
|
|
{
|
|
pshape->Release();
|
|
pshape = 0;
|
|
}
|
|
cellFontDeleteGlyph(&Font, glyph);
|
|
return pshape;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxGlyphRaster* GFxExternalFontPS3::GetGlyphRaster(UInt glyphIndex,
|
|
UInt glyphSize)
|
|
{
|
|
if (!IsHintedRasterGlyph(glyphIndex, glyphSize))
|
|
return 0;
|
|
|
|
return 0;
|
|
//GlyphType& glyph = Glyphs[glyphIndex];
|
|
|
|
//if (LastFontHeight != glyphSize)
|
|
//{
|
|
// // FT_Set_Pixel_Sizes is expensive. Avoid calling it often.
|
|
// FT_Set_Pixel_Sizes(Face, glyphSize, glyphSize);
|
|
// LastFontHeight = glyphSize;
|
|
//}
|
|
|
|
//int err = FT_Load_Glyph(Face, glyph.FtIndex, FT_LOAD_DEFAULT);
|
|
//if (err)
|
|
// return 0;
|
|
|
|
//err = FT_Render_Glyph(Face->glyph, FT_RENDER_MODE_MONO);
|
|
//if (err)
|
|
// return 0;
|
|
|
|
//if (pRaster.GetPtr() == 0)
|
|
// pRaster = *new GFxGlyphRaster;
|
|
|
|
//decomposeGlyphBitmap(Face->glyph->bitmap,
|
|
// Face->glyph->bitmap_left,
|
|
// Face->glyph->bitmap_top,
|
|
// pRaster);
|
|
//return pRaster;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Float GFxExternalFontPS3::GetAdvance(UInt glyphIndex) const
|
|
{
|
|
if (glyphIndex == (UInt)-1)
|
|
return GetDefaultGlyphWidth();
|
|
|
|
return Glyphs[glyphIndex].Advance;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Float GFxExternalFontPS3::GetKerningAdjustment(UInt lastCode, UInt thisCode) const
|
|
{
|
|
if(FontOK == CELL_OK)
|
|
{
|
|
CellFontKerning kerning;
|
|
CellFont tmpFont = Font;
|
|
int err = cellFontGetKerning(&tmpFont, lastCode, thisCode, &kerning);
|
|
if (err == CELL_OK)
|
|
return kerning.offsetX;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Float GFxExternalFontPS3::GetGlyphWidth(UInt glyphIndex) const
|
|
{
|
|
if (glyphIndex == (UInt)-1)
|
|
return GetDefaultGlyphWidth();
|
|
|
|
const GRectF& r = Glyphs[glyphIndex].Bounds;
|
|
return r.Width();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Float GFxExternalFontPS3::GetGlyphHeight(UInt glyphIndex) const
|
|
{
|
|
if (glyphIndex == (UInt)-1)
|
|
return GetDefaultGlyphHeight();
|
|
|
|
const GRectF& r = Glyphs[glyphIndex].Bounds;
|
|
return r.Height();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GRectF& GFxExternalFontPS3::GetGlyphBounds(UInt glyphIndex, GRectF* prect) const
|
|
{
|
|
if (glyphIndex == (UInt)-1)
|
|
prect->SetRect(GetDefaultGlyphWidth(), GetDefaultGlyphHeight());
|
|
else
|
|
*prect = Glyphs[glyphIndex].Bounds;
|
|
return *prect;
|
|
}
|
|
|
|
static void* GFxFontProviderPS3_malloc( void*obj, uint32_t size )
|
|
{
|
|
GUNUSED(obj);
|
|
return GALLOC(size, GStat_Default_Mem);
|
|
}
|
|
static void GFxFontProviderPS3_free( void*obj, void*p )
|
|
{
|
|
GUNUSED(obj);
|
|
GFREE(p);
|
|
}
|
|
static void* GFxFontProviderPS3_realloc( void*obj, void* p, uint32_t size )
|
|
{
|
|
GUNUSED(obj);
|
|
return GREALLOC(p, size, GStat_Default_Mem);
|
|
}
|
|
static void* GFxFontProviderPS3_calloc( void*obj, uint32_t numb, uint32_t blockSize )
|
|
{
|
|
GUNUSED(obj);
|
|
void* p = GALLOC(numb * blockSize, GStat_Default_Mem);
|
|
memset(p, 0, numb * blockSize);
|
|
return p;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxFontProviderPS3::GFxFontProviderPS3(UInt fontCacheSize, UInt numUserFontEntries, UInt firstId)
|
|
{
|
|
FontOK = cellSysmoduleLoadModule(CELL_SYSMODULE_FONT);
|
|
if (FontOK == CELL_OK)
|
|
FontOK = cellSysmoduleLoadModule(CELL_SYSMODULE_FREETYPE);
|
|
if (FontOK == CELL_OK)
|
|
cellSysmoduleLoadModule(CELL_SYSMODULE_FONTFT);
|
|
|
|
if (FontOK == CELL_OK)
|
|
{
|
|
FontFileCache.Resize(fontCacheSize/4);
|
|
UserFontEntries.Resize(numUserFontEntries);
|
|
|
|
FontConfig.FileCache.buffer = &FontFileCache[0]; // Set the file read cache
|
|
FontConfig.FileCache.size = (uint32_t)(FontFileCache.GetSize() * 4);
|
|
FontConfig.userFontEntrys = &UserFontEntries[0]; // Set entry for the number of user
|
|
FontConfig.userFontEntryMax = (uint32_t)UserFontEntries.GetSize();
|
|
FontOK = cellFontInit(&FontConfig);
|
|
if(FontOK == CELL_OK)
|
|
{
|
|
CellFontLibraryConfigFT_initialize(&FtConfig); // Initial setting
|
|
|
|
FtConfig.MemoryIF.Object = NULL;
|
|
FtConfig.MemoryIF.Malloc = GFxFontProviderPS3_malloc;
|
|
FtConfig.MemoryIF.Free = GFxFontProviderPS3_free;
|
|
FtConfig.MemoryIF.Realloc = GFxFontProviderPS3_realloc;
|
|
FtConfig.MemoryIF.Calloc = GFxFontProviderPS3_calloc;
|
|
|
|
FontOK = cellFontInitLibraryFreeType(&FtConfig, &Library);
|
|
if (FontOK != CELL_OK)
|
|
{
|
|
cellFontEnd();
|
|
}
|
|
}
|
|
}
|
|
|
|
NextFontId = firstId;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxFontProviderPS3::~GFxFontProviderPS3()
|
|
{
|
|
if (FontOK == CELL_OK)
|
|
{
|
|
FontOK = cellFontEndLibrary(Library);
|
|
if (FontOK == CELL_OK)
|
|
{
|
|
cellFontEnd();
|
|
}
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxFontProviderPS3::MapSystemFont(const char* fontName, UInt fontFlags,
|
|
uint32_t fontType, uint32_t fontMap,
|
|
GFxFont::NativeHintingRange vectorHintingRange,
|
|
GFxFont::NativeHintingRange rasterHintingRange,
|
|
UInt maxVectorHintedSize,
|
|
UInt maxRasterHintedSize)
|
|
{
|
|
// Mask flags to be safe.
|
|
fontFlags &= GFxFont::FF_CreateFont_Mask;
|
|
fontFlags |= GFxFont::FF_DeviceFont | GFxFont::FF_NativeHinting;
|
|
|
|
GFxFontInfoPS3 font;
|
|
font.FontName = fontName;
|
|
font.FontFlags = fontFlags;
|
|
font.FontData = 0;
|
|
font.FontDataSize = 0;
|
|
font.SubNum = 0;
|
|
font.UniqueId = 0;
|
|
font.Type.map = fontMap;
|
|
font.Type.type = fontType;
|
|
font.VectorHintingRange = vectorHintingRange;
|
|
font.RasterHintingRange = rasterHintingRange;
|
|
font.MaxVectorHintedSize = maxVectorHintedSize;
|
|
font.MaxRasterHintedSize = maxRasterHintedSize;
|
|
Fonts.PushBack(font);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxFontProviderPS3::MapFontToFile(const char* fontName, UInt fontFlags,
|
|
const char* fileName, uint32_t subNum,
|
|
GFxFont::NativeHintingRange vectorHintingRange,
|
|
GFxFont::NativeHintingRange rasterHintingRange,
|
|
UInt maxVectorHintedSize,
|
|
UInt maxRasterHintedSize)
|
|
{
|
|
// Mask flags to be safe.
|
|
fontFlags &= GFxFont::FF_CreateFont_Mask;
|
|
fontFlags |= GFxFont::FF_DeviceFont | GFxFont::FF_NativeHinting;
|
|
|
|
GFxFontInfoPS3 font;
|
|
font.FontName = fontName;
|
|
font.FontFlags = fontFlags;
|
|
font.FileName = fileName;
|
|
font.FontData = 0;
|
|
font.FontDataSize = 0;
|
|
font.SubNum = subNum;
|
|
font.UniqueId = NextFontId++;
|
|
font.Type.map = ~0U;
|
|
font.Type.type = ~0U;
|
|
font.VectorHintingRange = vectorHintingRange;
|
|
font.RasterHintingRange = rasterHintingRange;
|
|
font.MaxVectorHintedSize = maxVectorHintedSize;
|
|
font.MaxRasterHintedSize = maxRasterHintedSize;
|
|
Fonts.PushBack(font);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxFontProviderPS3::MapFontToMemory(const char* fontName, UInt fontFlags,
|
|
const char* fontData, UInt dataSize,
|
|
uint32_t subNum,
|
|
GFxFont::NativeHintingRange vectorHintingRange,
|
|
GFxFont::NativeHintingRange rasterHintingRange,
|
|
UInt maxVectorHintedSize,
|
|
UInt maxRasterHintedSize)
|
|
{
|
|
// Mask flags to be safe.
|
|
fontFlags &= GFxFont::FF_CreateFont_Mask;
|
|
fontFlags |= GFxFont::FF_DeviceFont | GFxFont::FF_NativeHinting;
|
|
|
|
GFxFontInfoPS3 font;
|
|
font.FontName = fontName;
|
|
font.FontFlags = fontFlags;
|
|
font.FontData = fontData;
|
|
font.FontDataSize = dataSize;
|
|
font.SubNum = subNum;
|
|
font.UniqueId = NextFontId++;
|
|
font.Type.map = ~0U;
|
|
font.Type.type = ~0U;
|
|
font.VectorHintingRange = vectorHintingRange;
|
|
font.RasterHintingRange = rasterHintingRange;
|
|
font.MaxVectorHintedSize = maxVectorHintedSize;
|
|
font.MaxRasterHintedSize = maxRasterHintedSize;
|
|
Fonts.PushBack(font);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
GFxFont* GFxFontProviderPS3::CreateFont(const char* name, UInt fontFlags)
|
|
{
|
|
if (FontOK != CELL_OK)
|
|
return 0;
|
|
|
|
// Mask flags to be safe.
|
|
fontFlags &= GFxFont::FF_CreateFont_Mask;
|
|
fontFlags |= GFxFont::FF_DeviceFont;
|
|
|
|
UInt i;
|
|
for (i = 0; i < Fonts.GetSize(); ++i)
|
|
{
|
|
GFxFontInfoPS3& font = Fonts[i];
|
|
if (font.FontName.CompareNoCase(name) == 0 &&
|
|
(font.FontFlags & GFxFont::FF_Style_Mask) == (fontFlags & GFxFont::FF_Style_Mask))
|
|
{
|
|
GFxExternalFontPS3* newFont = new GFxExternalFontPS3(this, Library, &font);
|
|
if (newFont && !newFont->IsValid())
|
|
{
|
|
newFont->Release();
|
|
return 0;
|
|
}
|
|
return newFont;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void GFxFontProviderPS3::LoadFontNames(GStringHash<GString>& fontnames)
|
|
{
|
|
for (UInt i = 0; i < Fonts.GetSize(); ++i)
|
|
{
|
|
fontnames.Set(Fonts[i].FontName, Fonts[i].FontName);
|
|
}
|
|
}
|