#if !defined(ECERE_NOTRUETYPE)
+#if !defined(ECERE_VANILLA)
+import "edtaa3func"
+
+static void ComputeOutline(byte *out, byte *src, uint w, uint h, float size, float fade)
+{
+ uint i, numPixels = w * h;
+ short * distx = new short[2 * numPixels], * disty = distx + numPixels;
+ float * data = new0 float[4 * numPixels], * gx = data + numPixels, * gy = gx + numPixels, * dist = gy + numPixels;
+ float rb = Max(1.5f, size), ra = rb - (rb-1)*fade - 1;
+ float inv_rw = 1/(rb-ra);
+
+ for(i = 0; i < numPixels; i++)
+ data[i] = src[i] / 255.0f;
+
+ computegradient(data, w, h, gx, gy);
+ edtaa3(data, gx, gy, w, h, distx, disty, dist);
+
+ for(i = 0; i < numPixels; i++)
+ {
+ float value = 1 - Max(0.0f, Min(1.0f, (dist[i]-ra)*inv_rw));
+ out[i] = (byte)(255 * value * value);
+ }
+ delete distx;
+ delete data;
+}
+
+static void BlitOutline(byte * dst, int dx, int dy, int w, int h, byte * src, int sx, int sy, int sw, int sh, int srcStride)
+{
+ sh = Min(h - dy, sh);
+ sw = Min(w - dx, sw);
+ if(sw > 0 && sh > 0)
+ {
+ int y;
+ for(y = 0; y < sh; y++)
+ memcpy(dst + w * (dy+y) + dx, src + srcStride * (sy+y) + sx, sw);
+ }
+}
+
+static void MeasureOutline(byte * image, int w, int h, int * _x1, int * _y1, int * _x2, int * _y2)
+{
+ int x1 = MAXINT, y1 = MAXINT, x2 = MININT, y2 = MININT;
+ int x, y;
+ for(x = 0; x < w && x1 == MAXINT; x++)
+ {
+ for(y = 0; y < h; y++)
+ if(image[(y*w)+x])
+ {
+ x1 = x;
+ break;
+ }
+ }
+ for(x = w-1; x >= 0 && x2 == MININT; x--)
+ {
+ for(y = 0; y < h; y++)
+ if(image[(y*w)+x])
+ {
+ x2 = x;
+ break;
+ }
+ }
+ for(y = 0; y < h && y1 == MAXINT; y++)
+ {
+ for(x = 0; x < w; x++)
+ if(image[(y*w)+x])
+ {
+ y1 = y;
+ break;
+ }
+ }
+ for(y = h-1; y >= 0 && y2 == MININT; y--)
+ {
+ for(x = 0; x < w; x++)
+ if(image[(y*w)+x])
+ {
+ y2 = y;
+ break;
+ }
+ }
+ *_x1 = x1;
+ *_y1 = y1;
+ *_x2 = x2;
+ *_y2 = y2;
+}
+
+#endif
+
#define MAX_FONT_LINK_ENTRIES 10
static HB_Script theCurrentScript;
-static unichar UTF16GetChar(uint16 *string, int * nw)
+static unichar UTF16GetChar(const uint16 *string, int * nw)
{
unichar ch;
if(HB_IsHighSurrogate(string[0]) && HB_IsLowSurrogate(string[1]))
return ch;
}
-static HB_Bool hb_stringToGlyphs(HB_Font font, uint16 * string, uint length, HB_Glyph *glyphs, uint *numGlyphs, HB_Bool rightToLeft)
+static HB_Bool hb_stringToGlyphs(HB_Font font, const uint16 * string, uint length, HB_Glyph *glyphs, uint *numGlyphs, HB_Bool rightToLeft)
{
FT_Face face = ((FontEntry)font->userData).face;
int glyph_pos = 0;
}
}
-static HB_Bool hb_canRender(HB_Font font, uint16 * string, uint length)
+static HB_Bool hb_canRender(HB_Font font, const uint16 * string, uint length)
{
FT_Face face = ((FontEntry)font->userData).face;
int c, nw;
~FontEntry()
{
- char * fileName = (char *)key;
- delete fileName;
+ delete (char *)key;
delete buffer;
if(hbFace)
HB_FreeFace(hbFace);
{
GlyphInfo glyphs[256];
Bitmap bitmap { };
+ BinaryTree outlines { };
+ int cellWidth, cellHeight;
void Render(Font font, int startFontEntry, DisplaySystem displaySystem)
{
FontEntry fontEntry = null;
FT_Face faces[128];
float scales[128];
- bool isGlyph = (uint)key & 0x80000000;
- int curScript = ((uint)key & 0x7F000000) >> 24;
+ bool isGlyph = ((uint)key & 0x80000000) != 0;
+ //int curScript = ((uint)key & 0x7F000000) >> 24;
unichar testChar = 0;
/*
if(isGlyph)
}
//FT_Set_Char_Size(fontEntry.face, (int)(font.size * 64), (int)(font.size * 64), 96, 96);
fontEntry.scale = FaceSetCharSize(fontEntry.face, font.size);
+ if(!font.scale)
+ font.scale = fontEntry.scale;
if(!c)
{
if(!fontEntry.face->units_per_EM)
maxHeight = Max(maxHeight, ((faces[c]->glyph->metrics.height + 64 + (64 - (faces[c]->glyph->metrics.height & 0x3F))) >> 6));
//maxHeight = Max(maxHeight, ((faces[c]->glyph->metrics.height) >> 6));
}
- cellWidth = maxWidth;
- cellHeight = maxHeight;
+ this.cellWidth = cellWidth = maxWidth;
+ this.cellHeight = cellHeight = maxHeight;
- width = pow2i(maxWidth * 16);
- height = pow2i(maxHeight * 8);
+ width = maxWidth * 16;
+ height = maxHeight * 8;
+
+ if(true)
+ {
+ width = pow2i(height * 16);
+ height = pow2i(height * 8);
+ }
if(bitmap.Allocate(null, width, height, 0, pixelFormatAlpha, false /*true*/))
{
{
int total = 0;
int numPixels = 0;
- int max;
+ //int max;
if(slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO)
{
for(j = y, q = 0; j<yMax; j++)
q += slot->bitmap.pitch;
}
}
- max = numPixels ? (total / numPixels) : 1;
+ //max = numPixels ? (total / numPixels) : 1;
for(j = y, q = 0; j<yMax; j++)
{
if(displaySystem && displaySystem.pixelFormat != pixelFormat4) // TODO: Add none PixelFormat
{
+ bitmap.keepData = true; // For outlines
displaySystem.Lock();
#if defined(__WIN32__)
// Is this check still required?
}
#endif
}
+
+ void RenderOutline(GlyphPack outline, Font font, DisplaySystem displaySystem)
+ {
+#if !defined(ECERE_NOTRUETYPE) && !defined(ECERE_VANILLA)
+ unichar c;
+ int pCellWidth = this.cellWidth, pCellHeight = this.cellHeight;
+ int cellWidth, cellHeight;
+ int width, height;
+ uintptr key = outline.key;
+ float outlineSize = (float)(key >> 16);
+ float fade = ((uint32)key & 0xFFFF) / 255.f;
+ GlyphInfo * widest = null, * highest = null;
+ uint widestIndex = 0, highestIndex = 0;
+ GlyphInfo * glyph;
+ int minX1 = MAXINT, minY1 = MAXINT;
+ int maxX2 = MININT, maxY2 = MININT;
+ int timesBigger = 2;
+ byte * bigger = new byte[pCellWidth * pCellHeight * timesBigger*timesBigger];
+ byte * field = new byte[pCellWidth * pCellHeight * timesBigger*timesBigger];
+ int ox, oy;
+
+ // Test biggest glyphs to determine cell width & height:
+ for(c = 0; c < 128; c++)
+ {
+ glyph = &glyphs[c];
+ if(glyph->w > (widest ? widest->w : 0))
+ widest = glyph, widestIndex = c;
+ if(glyph->h > (highest ? highest->h : 0))
+ highest = glyph, highestIndex = c;
+ }
+
+ cellWidth = 0;
+ cellHeight = 0;
+ for(glyph = widest; glyph; glyph = (glyph == widest && glyph != highest) ? highest : null)
+ {
+ int index = (glyph == widest) ? widestIndex : highestIndex;
+ int x = (index & 0xF) * pCellWidth, y = (index >> 4) * pCellHeight;
+ int w = pCellWidth * timesBigger, h = pCellHeight * timesBigger;
+ int x1,y1,x2,y2;
+
+ memset(bigger, 0, w * h);
+ BlitOutline(bigger, (w - pCellWidth)/2, (h - pCellHeight)/2, w, h, bitmap.picture, x, y, pCellWidth, pCellHeight, bitmap.width);
+ ComputeOutline(field, bigger, w, h, outlineSize, fade);
+ MeasureOutline(field, w, h, &x1, &y1, &x2, &y2);
+ minX1 = Min(minX1, x1);
+ minY1 = Min(minY1, y1);
+ maxX2 = Max(maxX2, x2);
+ maxY2 = Max(maxY2, y2);
+ }
+ {
+ int x1 = (timesBigger*pCellWidth - pCellWidth) / 2, x2 = x1 + pCellWidth-1;
+ int y1 = (timesBigger*pCellHeight - pCellHeight) / 2, y2 = y1 + pCellHeight-1;
+ ox = -Max(0, x1 - minX1);
+ oy = -Max(0, y1 - minY1);
+ cellWidth = pCellWidth - ox + Max(0, (maxX2 > x2) ? (maxX2 - x2) : 0);
+ cellHeight = pCellHeight - oy + Max(0, (maxY2 > y2) ? (maxY2 - y2) : 0);
+ }
+
+ width = cellWidth * 16;
+ height = cellHeight * 8;
+ if(true) //TEXTURES_MUST_BE_POWER_OF_2)
+ {
+ width = pow2i(width);
+ height = pow2i(height);
+ }
+
+ if(outline.bitmap.Allocate(null, width, height, 0, pixelFormatAlpha, false))
+ {
+ Bitmap bitmap = outline.bitmap;
+ byte * picture = (byte *)bitmap.picture;
+ memset(picture, 0, width * height);
+
+ for(c = 0; c < 128; c++)
+ {
+ GlyphInfo * glyph = &outline.glyphs[c];
+ int x1 = MAXINT, y1 = MAXINT, x2 = MININT, y2 = MININT;
+ int w = 0, h = 0;
+ memset(bigger, 0, cellWidth * cellHeight);
+ BlitOutline(bigger, -ox, -oy, cellWidth, cellHeight,
+ this.bitmap.picture,
+ (c & 0xF) * pCellWidth, (c >> 4) * pCellHeight,
+ pCellWidth, pCellHeight,
+ this.bitmap.width);
+
+ // Don't waste time on empty glyphs
+ if(glyphs[c].w)
+ {
+ ComputeOutline(field, bigger, cellWidth, cellHeight, outlineSize, fade);
+ MeasureOutline(field, cellWidth, cellHeight, &x1, &y1, &x2, &y2);
+ if(x2 > x1) w = x2-x1+1;
+ if(y2 > y1) h = y2-y1+1;
+ }
+ else
+ memset(field, 0, cellWidth * cellHeight);
+
+ glyph->x = (c & 0xF) * cellWidth;
+ glyph->y = (c >> 4) * cellHeight;
+ BlitOutline(picture, glyph->x, glyph->y, width, height, field, 0, 0, cellWidth, cellHeight, cellWidth);
+
+ glyph->glyphNo = glyphs[c].glyphNo;
+ glyph->scale = glyphs[c].scale;
+ glyph->left = glyphs[c].left + ox;
+ glyph->top = glyphs[c].top + oy;
+ if(w) { glyph->x += x1; glyph->left += x1; }
+ if(h) { glyph->y += y1; glyph->top += y1; }
+ glyph->w = w;
+ glyph->h = h;
+ glyph->bx = glyphs[c].bx;
+ glyph->by = glyphs[c].by;
+ glyph->ax = glyphs[c].ax;
+ glyph->ay = glyphs[c].ay;
+ }
+
+ #if 0
+ {
+ int c;
+ char fileName[256];
+ static int fid = 0;
+ for(c = 0; c<256; c++)
+ outline.bitmap.palette[c] = ColorAlpha { 255, { (byte)c,(byte)c,(byte)c } };
+ outline.bitmap.pixelFormat = pixelFormat8;
+
+ /*
+ //strcpy(fileName, faceName);
+ if(flags)
+ strcat(fileName, "Bold");
+ */
+ sprintf(fileName, "outline%d", fid++);
+ ChangeExtension(fileName, "pcx", fileName);
+
+ outline.bitmap.Save(fileName, null, 0);
+ outline.bitmap.pixelFormat = pixelFormatAlpha;
+ }
+
+ /*{
+ static int num = 0;
+ char fileName[MAX_LOCATION];
+
+ sprintf(fileName, "template%03d.png", num);
+ bitmap.Save(fileName, null, 0);
+ sprintf(fileName, "outline%03d.png", num++);
+ outline.bitmap.Save(fileName, null, 0);
+ }*/
+ #endif
+ if(displaySystem && displaySystem.pixelFormat != pixelFormat4) // TODO: Add none PixelFormat
+ {
+ displaySystem.Lock();
+#if defined(__WIN32__)
+ // Is this check still required?
+ if(displaySystem.driver == class(OpenGLDisplayDriver) ||
+ displaySystem.driver == class(Direct3D8DisplayDriver) ||
+ displaySystem.driver == class(Direct3D9DisplayDriver))
+#endif
+ bitmap.MakeDD(displaySystem);
+ displaySystem.Unlock();
+ }
+ }
+ delete bigger;
+ delete field;
+#endif
+ }
}
#if !defined(ECERE_NOTRUETYPE)
}
*numGlyphs = shaper_item.num_glyphs;
- *rightToLeft = shaper_item.item.bidiLevel % 2;
+ *rightToLeft = (bool)(shaper_item.item.bidiLevel % 2);
return shaper_item.glyphs;
}
}
#endif
}
+ public property int ascent
+ {
+ get { return (int)(this ? ascent * scale : 0); }
+ }
};
public class LFBDisplay : struct
bool opaqueText;
int xOffset;
bool writingText;
+ bool writingOutline;
Bitmap bitmap;
{
char entryName[1024];
char fontFileName[1024];
- uint32 type;
- int size = 1024;
- int sizeFileName = 1024;
+ DWORD type;
+ DWORD size = 1024;
+ DWORD sizeFileName = 1024;
char * occurence;
- if(RegEnumValue(key, value++, entryName, (PDWORD)&size, null, (PDWORD)&type, (LPBYTE)fontFileName, (PDWORD)&sizeFileName) != ERROR_SUCCESS)
+ if(RegEnumValue(key, value++, entryName, &size, null, (PDWORD)&type, (LPBYTE)fontFileName, &sizeFileName) != ERROR_SUCCESS)
break;
- if((occurence = SearchString((char *)entryName, 0, (char *)font->elfFullName, false, false)))
+ if((occurence = SearchString(entryName, 0, (const char *)font->elfFullName, false, false)))
{
int c;
for(c = (int)(occurence - entryName) - 1; c >= 0; c--)
}
#endif
+#if !defined(ECERE_NOTRUETYPE)
static int utf16BufferSize = 0;
static uint16 * utf16 = null;
+#endif
public class LFBDisplayDriver : DisplayDriver
{
LFBDisplay lfbDisplay = display ? display.driverData : null;
LFBSurface lfbSurface = surface.driverData;
uint index;
- if(display) color = color /*& 0xFFFFFF*/;
+ //if(display) color = color & 0xFFFFFF;
lfbSurface.foregroundRgb = color;
if(lfbSurface.font && lfbDisplay)
{
LFBDisplay lfbDisplay = display ? display.driverData : null;
LFBSurface lfbSurface = surface.driverData;
- color = color /*& 0xFFFFFF*/;
+ //color = color & 0xFFFFFF;
switch(lfbSurface.bitmap.pixelFormat)
{
case pixelFormat8:
}
else
{
- if(surface.background.a == 255 || lfbSurface.clearing)
+ if(!surface.blend || surface.background.a == 255 || lfbSurface.clearing)
{
switch(GetColorDepthShifts(lfbSurface.bitmap.pixelFormat))
{
int c;
for(c = 0; c < w; c++, dest++)
{
- Color destColor;
+ Color destColor = 0;
if(pixelFormat == pixelFormat565) { destColor = (Color)*(Color565 *)dest; }
else if(pixelFormat == pixelFormat555) { destColor = (Color)*(Color555 *)dest; }
else if(pixelFormat == pixelFormat444) { destColor = (Color)*(Color444 *)dest; }
ColorAlpha * backsrc;
ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
- if(flip < 0) source += sw-1;
+ if(flip) source += sw-1;
adddest -= w;
yerr = 0;
for(y=0; y<sh; y++)
AlphaWriteMode alphaWrite = surface.alphaWrite;
if(src.alphaBlend && surface.blend)
{
- int x, y;
- uint xerr,yerr;
uint adddest = lfbSurface.bitmap.stride, addsource = src.stride;
- ColorAlpha * backsrc;
ColorAlpha * source = ((ColorAlpha *) src.picture) + sy * addsource + sx;
ColorAlpha * dest = ((ColorAlpha *) lfbSurface.bitmap.picture) + dy * adddest + dx;
float scaleX = (float)sw / w;
int x0 = x * sw / w;
int x1 = Min(x0 + 1, sw - 1);
float beta = x * scaleX - x0;
- ColorAlpha color;
ColorAlpha src00, src01, src10, src11;
float a1,r1,g1,b1,a2,r2,g2,b2;
float a,r,g,b;
float a = 0, r = 0, g = 0, b = 0;
int numPixels = 0;
int i, j;
- ColorAlpha color;
for (i = y0; i <= y1; i++)
for (j = x0; j <= x1; j++)
{
g /= numPixels;
b /= numPixels;
{
- ColorAlpha src = *source;
ColorAlpha dst = *dest;
int cr = (int)(a * r / 255 + ((255 - a) * dst.color.r / 255));
int cg = (int)(a * g / 255 + ((255 - a) * dst.color.g / 255));
}
}
- Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
+ Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
{
void * result = null;
{
char fileName[MAX_LOCATION];
bool fakeItalic = flags.italic;
- char linkCfgPath[MAX_LOCATION];
int fontID = 0;
#if !defined(__WIN32__)
File linkCfg;
#endif
- char * ecereFonts = getenv("ECERE_FONTS");
+ const char * ecereFonts = getenv("ECERE_FONTS");
if(!ecereFonts) ecereFonts = "<:ecere>";
#if !defined(__WIN32__)
- strcpy(linkCfgPath, ecereFonts);
- PathCat(linkCfgPath, "linking.cfg");
- linkCfg = FileOpen(linkCfgPath, read);
+ {
+ char linkCfgPath[MAX_LOCATION];
+
+ strcpy(linkCfgPath, ecereFonts);
+ PathCat(linkCfgPath, "linking.cfg");
+ linkCfg = FileOpen(linkCfgPath, read);
+ }
#endif
strcpy(fileName, faceName);
strcpy(font.faceName, faceName);
strcpy(logFont.lfFaceName, faceName);
fontData.flags = flags;
- EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (DWORD)&fontData, 0);
+ EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
if(!fontData.fileName[0] && flags.bold)
{
fontData.forgive = true;
- EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (DWORD)&fontData, 0);
+ EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
}
if(!fontData.fileName[0])
{
// Fake italic
fontData.flags.italic = false;
- EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (DWORD)&fontData, 0);
+ EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
fakeItalic = true;
}
// printf("Locating %s\n", faceName);
if(matched)
{
- FcPatternGetString(matched, FC_FAMILY, 0, &family);
+ FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
//printf("Fontconfig returned %s\n", family);
}
if(matched && (result == FcResultMatch /*|| result == FcResultNoId*/) /*&& !strcmpi(family, faceName)*/)
{
double fontSize;
- FcPatternGetString (matched, FC_FILE, 0, &fileName2);
+ FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName2);
FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
strcpy(fileName, fileName2);
!RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\FontLink\\SystemLink",0,KEY_READ,&key))
{
// int value = 0;
- uint32 type;
- int size = 1024;
- RegQueryValueEx(key, faceName, null, (LPDWORD)&type, (LPBYTE)links, (LPDWORD)&size);
+ DWORD type;
+ DWORD size = 1024;
+ RegQueryValueEx(key, faceName, null, &type, (LPBYTE)links, &size);
memset(links + size, 0, 1024 - size);
RegCloseKey(key);
}
matched = FcFontMatch (0, pattern, &result);
if(matched)
{
- FcPatternGetString(matched, FC_FAMILY, 0, &family);
+ FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
// printf("Fontconfig returned %s\n", family);
}
if(matched && (result == FcResultMatch /*|| result == FcResultNoId*/) &&
- FcPatternGetString(matched, FC_FAMILY, 0, &family) == FcResultMatch /*&& !strcmpi(family, links + linksPos + c + 1)*/)
+ FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch /*&& !strcmpi(family, links + linksPos + c + 1)*/)
{
double fontSize;
- FcPatternGetString (matched, FC_FILE, 0, &fileName2);
+ FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName2);
FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
strcpy(fileName, fileName2);
}
#if !defined(ECERE_NOTRUETYPE)
- void ::ProcessString(Font font, DisplaySystem displaySystem, byte * text, int len,
+ void ::ProcessString(Font font, DisplaySystem displaySystem, const byte * text, int len,
void (* callback)(Surface surface, Display display, int x, int y, GlyphInfo * glyph, Bitmap bitmap),
Surface surface, Display display, int * x, int y)
{
if(font && font.fontEntries && font.fontEntries[0])
{
+ LFBSurface lfbSurface = surface ? surface.driverData : null;
int previousGlyph = 0;
FT_Face previousFace = 0;
int c, nb, glyphIndex = 0;
- unichar lastPack = 0;
- GlyphPack pack = font.asciiPack;
- int wc;
- uint * glyphs;
+ unichar lastPack = lfbSurface && lfbSurface.writingOutline ? -1 : 0;
+ GlyphPack pack = font.asciiPack, outline = null;
+ int wc = 0;
+ uint * glyphs = null;
int numGlyphs = 0;
bool rightToLeft = false;
int fontEntryNum = 0;
for(c = 0; c < len || (numGlyphs && (rightToLeft ? (glyphIndex >= 0) : (glyphIndex < numGlyphs)));)
{
- uint glyphNo;
+ uint glyphNo = 0;
uint packNo;
if(numGlyphs && (rightToLeft ? (glyphIndex >= 0) : (glyphIndex < numGlyphs)))
{
else
{
HB_Script curScript = HB_Script_Common;
- byte * scriptStart = text + c;
- unichar nonASCIIch = 0;
+ const byte * scriptStart = text + c;
+ //unichar nonASCIIch = 0;
unichar ch;
unichar ahead = 0;
unichar testChar = 0;
- char * testLang = null;
+#if !defined(__WIN32__) && !defined(ECERE_NOFONTCONFIG)
+ const char * testLang = null;
+#endif
while(true)
{
HB_Script script = HB_Script_Common;
- ch = UTF8GetChar((char *)text + c, &nb);
- if(ch > 127) nonASCIIch = ch;
+ ch = UTF8GetChar((const char *)text + c, &nb);
+ //if(ch > 127) nonASCIIch = ch;
if(!nb) break;
if(ch == 32 && curScript)
{
if(a < c + len)
{
int nb;
- unichar ahead = UTF8GetChar((char *)text + a, &nb);
+ unichar ahead = UTF8GetChar((const char *)text + a, &nb);
if((ahead >= 0x590 && ahead <= 0x7C0) || (ahead >= 0xFB1D && ahead <= 0xFB4F) || (ahead >= 0xFB50 && ahead <= 0xFDFF))
script = curScript;
}
utf16 = renew utf16 uint16[max];
utf16BufferSize = max;
}
- wc = UTF8toUTF16BufferLen((char *)scriptStart, utf16, max, len);
+ wc = UTF8toUTF16BufferLen((const char *)scriptStart, utf16, max, len);
theCurrentScript = glyphScript = curScript;
}
switch(curScript)
case HB_Script_Arabic: testChar = 0x621; /*testLang = "ar"; */
//printf("Arabic ");
break;
- case HB_Script_Devanagari: testChar = 0x905; testLang = "sa";
+ case HB_Script_Devanagari: testChar = 0x905;
+#if !defined(__WIN32__) && !defined(ECERE_NOFONTCONFIG)
+ testLang = "sa";
+#endif
//printf("Devanagari ");
break;
case HB_Script_Hebrew: testChar = 0x05EA /*'ת'*/; /*testLang = "he"; */
char * family;
FontEntry fontEntry;
char * fileName = null;
- bool fakeItalic = false;
for(fontEntryNum = 0; fontEntryNum<MAX_FONT_LINK_ENTRIES; fontEntryNum++)
if(!font.fontEntries[fontEntryNum])
break;
matched = FcFontMatch (0, pattern, &result);
if(matched)
{
- FcPatternGetString(matched, FC_FAMILY, 0, &family);
+ FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
//printf("Fontconfig returned %s\n", family);
}
- if(matched && (result == FcResultMatch) && FcPatternGetString(matched, FC_FAMILY, 0, &family) == FcResultMatch)
+ if(matched && (result == FcResultMatch) && FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch)
{
- FcPatternGetString (matched, FC_FILE, 0, &fileName);
+ FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName);
FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
// printf("\nMatched to %s, %f\n", fileName, fontSize);
}
pack.bitmap.alphaBlend = true;
lastPack = packNo;
+#if !defined(ECERE_VANILLA)
+ if(lfbSurface && lfbSurface.writingOutline)
+ {
+ uint outlineNo = (((uint)surface.outline.size) << 16) | (uint16)(Min(surface.outline.fade, 257.0f) * 255);
+ outline = (GlyphPack)pack.outlines.Find(outlineNo);
+ if(!outline)
+ {
+ outline = { key = outlineNo };
+ pack.outlines.Add(outline);
+ pack.RenderOutline(outline, font, displaySystem);
+ }
+ }
+#endif
}
if(pack)
{
int index = rightToLeft ? (glyphIndex + 1) : (glyphIndex-1);
- GlyphInfo * glyph = &pack.glyphs[glyphNo & 0x7F];
+ GlyphInfo * glyph = &(outline ? outline : pack).glyphs[glyphNo & 0x7F];
int ax = (int)((numGlyphs ? shaper_item.advances[index] : glyph->ax) * glyph->scale);
int offset = numGlyphs ? shaper_item.offsets[index].x : 0;
previousFace = curFontEntry.face;
if(callback)
- callback(surface, display, ((*x) >> 6), y + (oy >> 6), glyph, pack.bitmap);
+ callback(surface, display, ((*x) >> 6), y + (oy >> 6), glyph, (outline ? outline : pack).bitmap);
*x += ax;
}
if(numGlyphs && (rightToLeft ? (glyphIndex < 0) : (glyphIndex == numGlyphs)))
}
#endif
- void FontExtent(DisplaySystem displaySystem, Font font, byte * text, int len, int * width, int * height)
+ void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
{
if(displaySystem && displaySystem.flags.text && len)
{
{
int w = 0;
#if !defined(ECERE_NOTRUETYPE)
- ProcessString(font, displaySystem, text, len, null, null, null, &w, 0);
+ ProcessString(font, displaySystem, (const byte *)text, len, null, null, null, &w, 0);
#endif
//*width = (w + 64 - w % 64) >> 6;
*width = w >> 6;
}
#endif
- void WriteText(Display display, Surface surface, int x, int y, byte * text, int len)
+ void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
{
LFBSurface lfbSurface = surface.driverData;
if(display && display.displaySystem.flags.text)
lfbSurface.writingText = true;
#if !defined(ECERE_NOTRUETYPE)
x <<= 6;
- ProcessString(lfbSurface.font, surface.displaySystem, text, len, OutputGlyph, surface, display, &x, y);
+ ProcessString(lfbSurface.font, surface.displaySystem, (const byte *)text, len, OutputGlyph, surface, display, &x, y);
#endif
lfbSurface.writingText = false;
}
void TextOpacity(Display display, Surface surface, bool opaque)
{
- LFBSurface lfbSurface = surface.driverData;
}
- void TextExtent(Display display, Surface surface, byte * text, int len, int * width, int * height)
+ void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
{
LFBSurface lfbSurface = surface.driverData;
FontExtent(surface.displaySystem, lfbSurface.font, text, len, width, height);
delete mesh.texCoords;
}
- bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh)
+ bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
{
bool result = false;
-
- if((!mesh.flags.vertices || mesh.vertices || (mesh.vertices = new Vector3Df[mesh.nVertices])) &&
- (!mesh.flags.normals || mesh.normals || (mesh.normals = new Vector3Df[mesh.nVertices])) &&
- (!mesh.flags.texCoords1 || mesh.texCoords || (mesh.texCoords = new Pointf [mesh.nVertices])))
+ if(mesh.nVertices == nVertices)
+ {
+ result = true;
+ // Same number of vertices, adding features (Leaves the other features pointers alone)
+ if(mesh.flags != flags)
+ {
+ if(!mesh.flags.vertices && flags.vertices)
+ {
+ if(flags.doubleVertices)
+ {
+ mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
+ }
+ else
+ mesh.vertices = new Vector3Df[nVertices];
+ }
+ if(!mesh.flags.normals && flags.normals)
+ {
+ if(flags.doubleNormals)
+ {
+ mesh.normals = (Vector3Df *)new Vector3D[nVertices];
+ }
+ else
+ mesh.normals = new Vector3Df[nVertices];
+ }
+ if(!mesh.flags.texCoords1 && flags.texCoords1)
+ mesh.texCoords = new Pointf[nVertices];
+ if(!mesh.flags.colors && flags.colors)
+ mesh.colors = new ColorRGBAf[nVertices];
+ }
+ }
+ else
+ {
result = true;
+ // New number of vertices, reallocate all current and new features
+ flags |= mesh.flags;
+ if(flags.vertices)
+ {
+ if(flags.doubleVertices)
+ {
+ mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
+ }
+ else
+ mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
+ }
+ if(flags.normals)
+ {
+ if(flags.doubleNormals)
+ {
+ mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
+ }
+ else
+ mesh.normals = renew mesh.normals Vector3Df[nVertices];
+ }
+ if(flags.texCoords1)
+ mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
+ if(flags.colors)
+ mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
+ }
return result;
}