Merge "Adding text metrics to renderscript."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cd1b8d3665
@@ -84,8 +84,6 @@ public class RsRenderStatesRS {
|
||||
private Allocation mTexTransparent;
|
||||
private Allocation mTexChecker;
|
||||
|
||||
private Allocation mAllocPV;
|
||||
|
||||
private Mesh mMbyNMesh;
|
||||
private Mesh mTorus;
|
||||
|
||||
@@ -95,7 +93,6 @@ public class RsRenderStatesRS {
|
||||
Font mFontSerifItalic;
|
||||
Font mFontSerifBoldItalic;
|
||||
Font mFontMono;
|
||||
|
||||
private Allocation mTextAlloc;
|
||||
|
||||
private ScriptC_rsrenderstates mScript;
|
||||
@@ -267,12 +264,15 @@ public class RsRenderStatesRS {
|
||||
mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
|
||||
mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8);
|
||||
|
||||
mTextAlloc = Allocation.createFromString(mRS, "String from allocation");
|
||||
|
||||
mScript.set_gFontSans(mFontSans);
|
||||
mScript.set_gFontSerif(mFontSerif);
|
||||
mScript.set_gFontSerifBold(mFontSerifBold);
|
||||
mScript.set_gFontSerifItalic(mFontSerifItalic);
|
||||
mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
|
||||
mScript.set_gFontMono(mFontMono);
|
||||
mScript.set_gTextAlloc(mTextAlloc);
|
||||
}
|
||||
|
||||
private void initMesh() {
|
||||
|
||||
@@ -42,6 +42,7 @@ rs_font gFontSerifBold;
|
||||
rs_font gFontSerifItalic;
|
||||
rs_font gFontSerifBoldItalic;
|
||||
rs_font gFontMono;
|
||||
rs_allocation gTextAlloc;
|
||||
|
||||
int gDisplayMode;
|
||||
|
||||
@@ -70,7 +71,7 @@ rs_program_fragment gProgFragmentMultitex;
|
||||
#pragma rs export_var(gProgStoreBlendNoneDepth, gProgStoreBlendNone, gProgStoreBlendAlpha, gProgStoreBlendAdd)
|
||||
#pragma rs export_var(gTexOpaque, gTexTorus, gTexTransparent, gTexChecker)
|
||||
#pragma rs export_var(gMbyNMesh, gTorusMesh)
|
||||
#pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono)
|
||||
#pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono, gTextAlloc)
|
||||
#pragma rs export_var(gLinearClamp, gLinearWrap, gMipLinearWrap, gMipLinearAniso8, gMipLinearAniso15, gNearestClamp)
|
||||
#pragma rs export_var(gCullBack, gCullFront, gCullNone)
|
||||
#pragma rs export_var(gVSConstants, gFSConstants, gVSInputs, gProgVertexCustom, gProgFragmentCustom, gProgFragmentMultitex)
|
||||
@@ -85,7 +86,7 @@ void init() {
|
||||
|
||||
void displayFontSamples() {
|
||||
rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
int yPos = 30;
|
||||
int yPos = 100;
|
||||
rsgBindFont(gFontSans);
|
||||
rsgDrawText("Sans font sample", 30, yPos);
|
||||
yPos += 30;
|
||||
@@ -107,6 +108,47 @@ void displayFontSamples() {
|
||||
yPos += 30;
|
||||
rsgBindFont(gFontMono);
|
||||
rsgDrawText("Monospace font sample", 30, yPos);
|
||||
yPos += 50;
|
||||
|
||||
// Now use text metrics to center the text
|
||||
uint width = rsgGetWidth();
|
||||
uint height = rsgGetHeight();
|
||||
int left = 0, right = 0, top = 0, bottom = 0;
|
||||
|
||||
rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
|
||||
rsgBindFont(gFontSerifBoldItalic);
|
||||
|
||||
rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
|
||||
int centeredPos = width / 2 - (right - left) / 2;
|
||||
rsgDrawText(gTextAlloc, centeredPos, yPos);
|
||||
yPos += 30;
|
||||
|
||||
const char* text = "Centered Text Sample";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
centeredPos = width / 2 - (right - left) / 2;
|
||||
rsgDrawText(text, centeredPos, yPos);
|
||||
yPos += 30;
|
||||
|
||||
rsgBindFont(gFontSans);
|
||||
text = "More Centered Text Samples";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
centeredPos = width / 2 - (right - left) / 2;
|
||||
rsgDrawText(text, centeredPos, yPos);
|
||||
yPos += 30;
|
||||
|
||||
// Now draw bottom and top right aligned text
|
||||
text = "Top-right aligned text";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
rsgDrawText(text, width - right, top);
|
||||
|
||||
text = "Top-left";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
rsgDrawText(text, -left, top);
|
||||
|
||||
text = "Bottom-right aligned text";
|
||||
rsgMeasureText(text, &left, &right, &top, &bottom);
|
||||
rsgDrawText(text, width - right, height + bottom);
|
||||
|
||||
}
|
||||
|
||||
void bindProgramVertexOrtho() {
|
||||
|
||||
@@ -258,14 +258,14 @@ void Context::displayDebugStats()
|
||||
sprintf(buffer, "Frame %i ms, Script %i ms", mTimeMSLastFrame, mTimeMSLastScript);
|
||||
float oldR, oldG, oldB, oldA;
|
||||
mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
|
||||
uint32_t bufferLen = strlen(buffer);
|
||||
|
||||
float shadowCol = 0.2f;
|
||||
float shadowCol = 0.1f;
|
||||
mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
|
||||
mStateFont.renderText(buffer, 5, getHeight() - 5);
|
||||
mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 5);
|
||||
|
||||
float textCol = 0.9f;
|
||||
mStateFont.setFontColor(textCol, textCol, textCol, 1.0f);
|
||||
mStateFont.renderText(buffer, 4, getHeight() - 6);
|
||||
mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
|
||||
mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 6);
|
||||
|
||||
mStateFont.setFontColor(oldR, oldG, oldB, oldA);
|
||||
}
|
||||
|
||||
@@ -84,34 +84,95 @@ void Font::invalidateTextureCache()
|
||||
}
|
||||
}
|
||||
|
||||
void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y)
|
||||
void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y)
|
||||
{
|
||||
FontState *state = &mRSC->mStateFont;
|
||||
|
||||
int nPenX = x + glyph->mBitmapLeft;
|
||||
int nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
|
||||
int32_t nPenX = x + glyph->mBitmapLeft;
|
||||
int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
|
||||
|
||||
state->appendMeshQuad(nPenX, nPenY, 0,
|
||||
glyph->mBitmapMinU, glyph->mBitmapMaxV,
|
||||
float u1 = glyph->mBitmapMinU;
|
||||
float u2 = glyph->mBitmapMaxU;
|
||||
float v1 = glyph->mBitmapMinV;
|
||||
float v2 = glyph->mBitmapMaxV;
|
||||
|
||||
nPenX + (int)glyph->mBitmapWidth, nPenY, 0,
|
||||
glyph->mBitmapMaxU, glyph->mBitmapMaxV,
|
||||
int32_t width = (int32_t) glyph->mBitmapWidth;
|
||||
int32_t height = (int32_t) glyph->mBitmapHeight;
|
||||
|
||||
nPenX + (int)glyph->mBitmapWidth, nPenY - (int)glyph->mBitmapHeight, 0,
|
||||
glyph->mBitmapMaxU, glyph->mBitmapMinV,
|
||||
|
||||
nPenX, nPenY - (int)glyph->mBitmapHeight, 0,
|
||||
glyph->mBitmapMinU, glyph->mBitmapMinV);
|
||||
state->appendMeshQuad(nPenX, nPenY, 0, u1, v2,
|
||||
nPenX + width, nPenY, 0, u2, v2,
|
||||
nPenX + width, nPenY - height, 0, u2, v1,
|
||||
nPenX, nPenY - height, 0, u1, v1);
|
||||
}
|
||||
|
||||
void Font::renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y)
|
||||
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int32_t x, int32_t y,
|
||||
uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH) {
|
||||
int32_t nPenX = x + glyph->mBitmapLeft;
|
||||
int32_t nPenY = y + glyph->mBitmapTop;
|
||||
|
||||
uint32_t endX = glyph->mBitmapMinX + glyph->mBitmapWidth;
|
||||
uint32_t endY = glyph->mBitmapMinY + glyph->mBitmapHeight;
|
||||
|
||||
FontState *state = &mRSC->mStateFont;
|
||||
uint32_t cacheWidth = state->getCacheTextureType()->getDimX();
|
||||
const uint8_t* cacheBuffer = state->getTextTextureData();
|
||||
|
||||
uint32_t cacheX = 0, cacheY = 0;
|
||||
int32_t bX = 0, bY = 0;
|
||||
for (cacheX = glyph->mBitmapMinX, bX = nPenX; cacheX < endX; cacheX++, bX++) {
|
||||
for (cacheY = glyph->mBitmapMinY, bY = nPenY; cacheY < endY; cacheY++, bY++) {
|
||||
if (bX < 0 || bY < 0 || bX >= (int32_t) bitmapW || bY >= (int32_t) bitmapH) {
|
||||
LOGE("Skipping invalid index");
|
||||
continue;
|
||||
}
|
||||
uint8_t tempCol = cacheBuffer[cacheY * cacheWidth + cacheX];
|
||||
bitmap[bY * bitmapW + bX] = tempCol;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds) {
|
||||
int32_t nPenX = x + glyph->mBitmapLeft;
|
||||
int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
|
||||
|
||||
int32_t width = (int32_t) glyph->mBitmapWidth;
|
||||
int32_t height = (int32_t) glyph->mBitmapHeight;
|
||||
|
||||
if (bounds->bottom > nPenY) {
|
||||
bounds->bottom = nPenY;
|
||||
}
|
||||
if (bounds->left > nPenX) {
|
||||
bounds->left = nPenX;
|
||||
}
|
||||
if (bounds->right < nPenX + width) {
|
||||
bounds->right = nPenX + width;
|
||||
}
|
||||
if (bounds->top < nPenY + height) {
|
||||
bounds->top = nPenY + height;
|
||||
}
|
||||
}
|
||||
|
||||
void Font::renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
|
||||
uint32_t start, int32_t numGlyphs,
|
||||
RenderMode mode, Rect *bounds,
|
||||
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH)
|
||||
{
|
||||
if(!mInitialized || numGlyphs == 0 || text == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int penX = x, penY = y;
|
||||
int glyphsLeft = 1;
|
||||
if(mode == Font::MEASURE) {
|
||||
if (bounds == NULL) {
|
||||
LOGE("No return rectangle provided to measure text");
|
||||
return;
|
||||
}
|
||||
// Reset min and max of the bounding box to something large
|
||||
bounds->set(1e6, -1e6, -1e6, 1e6);
|
||||
}
|
||||
|
||||
int32_t penX = x, penY = y;
|
||||
int32_t glyphsLeft = 1;
|
||||
if(numGlyphs > 0) {
|
||||
glyphsLeft = numGlyphs;
|
||||
}
|
||||
@@ -135,7 +196,17 @@ void Font::renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyp
|
||||
|
||||
// If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
|
||||
if(cachedGlyph->mIsValid) {
|
||||
drawCachedGlyph(cachedGlyph, penX, penY);
|
||||
switch(mode) {
|
||||
case FRAMEBUFFER:
|
||||
drawCachedGlyph(cachedGlyph, penX, penY);
|
||||
break;
|
||||
case BITMAP:
|
||||
drawCachedGlyph(cachedGlyph, penX, penY, bitmap, bitmapW, bitmapH);
|
||||
break;
|
||||
case MEASURE:
|
||||
measureCachedGlyph(cachedGlyph, penX, penY, bounds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
penX += (cachedGlyph->mAdvance.x >> 6);
|
||||
@@ -283,7 +354,7 @@ FontState::FontState()
|
||||
}
|
||||
|
||||
// Get the black gamma threshold
|
||||
int blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
|
||||
int32_t blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
|
||||
if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
|
||||
LOGD(" Setting text black gamma threshold to %s", property);
|
||||
blackThreshold = atoi(property);
|
||||
@@ -294,7 +365,7 @@ FontState::FontState()
|
||||
mBlackThreshold = (float)(blackThreshold) / 255.0f;
|
||||
|
||||
// Get the white gamma threshold
|
||||
int whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
|
||||
int32_t whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
|
||||
if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
|
||||
LOGD(" Setting text white gamma threshold to %s", property);
|
||||
whiteThreshold = atoi(property);
|
||||
@@ -397,13 +468,13 @@ bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *r
|
||||
|
||||
uint32_t cacheWidth = getCacheTextureType()->getDimX();
|
||||
|
||||
unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr();
|
||||
unsigned char *bitmapBuffer = bitmap->buffer;
|
||||
uint8_t *cacheBuffer = (uint8_t*)mTextTexture->getPtr();
|
||||
uint8_t *bitmapBuffer = bitmap->buffer;
|
||||
|
||||
uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
|
||||
for(cacheX = startX, bX = 0; cacheX < endX; cacheX ++, bX ++) {
|
||||
for(cacheY = startY, bY = 0; cacheY < endY; cacheY ++, bY ++) {
|
||||
unsigned char tempCol = bitmapBuffer[bY * bitmap->width + bX];
|
||||
uint8_t tempCol = bitmapBuffer[bY * bitmap->width + bX];
|
||||
cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol;
|
||||
}
|
||||
}
|
||||
@@ -487,7 +558,7 @@ void FontState::initTextTexture()
|
||||
mTextTexture->deferedUploadToTexture(mRSC, false, 0);
|
||||
|
||||
// Split up our cache texture into lines of certain widths
|
||||
int nextLine = 0;
|
||||
int32_t nextLine = 0;
|
||||
mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0));
|
||||
nextLine += mCacheLines.top()->mMaxHeight;
|
||||
mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0));
|
||||
@@ -519,8 +590,8 @@ void FontState::initVertexArrayBuffers()
|
||||
|
||||
// Four verts, two triangles , six indices per quad
|
||||
for(uint32_t i = 0; i < mMaxNumberOfQuads; i ++) {
|
||||
int i6 = i * 6;
|
||||
int i4 = i * 4;
|
||||
int32_t i6 = i * 6;
|
||||
int32_t i4 = i * 4;
|
||||
|
||||
indexPtr[i6 + 0] = i4 + 0;
|
||||
indexPtr[i6 + 1] = i4 + 1;
|
||||
@@ -713,7 +784,11 @@ void FontState::precacheLatin(Font *font) {
|
||||
}
|
||||
|
||||
|
||||
void FontState::renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y)
|
||||
void FontState::renderText(const char *text, uint32_t len, int32_t x, int32_t y,
|
||||
uint32_t startIndex, int32_t numGlyphs,
|
||||
Font::RenderMode mode,
|
||||
Font::Rect *bounds,
|
||||
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH)
|
||||
{
|
||||
checkInit();
|
||||
|
||||
@@ -730,7 +805,8 @@ void FontState::renderText(const char *text, uint32_t len, uint32_t startIndex,
|
||||
return;
|
||||
}
|
||||
|
||||
currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y);
|
||||
currentFont->renderUTF(text, len, x, y, startIndex, numGlyphs,
|
||||
mode, bounds, bitmap, bitmapW, bitmapH);
|
||||
|
||||
if(mCurrentQuadIndex != 0) {
|
||||
issueDrawCommand();
|
||||
@@ -738,32 +814,8 @@ void FontState::renderText(const char *text, uint32_t len, uint32_t startIndex,
|
||||
}
|
||||
}
|
||||
|
||||
void FontState::renderText(const char *text, int x, int y)
|
||||
{
|
||||
size_t textLen = strlen(text);
|
||||
renderText(text, textLen, 0, -1, x, y);
|
||||
}
|
||||
|
||||
void FontState::renderText(Allocation *alloc, int x, int y)
|
||||
{
|
||||
if(!alloc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *text = (const char *)alloc->getPtr();
|
||||
size_t allocSize = alloc->getType()->getSizeBytes();
|
||||
renderText(text, allocSize, 0, -1, x, y);
|
||||
}
|
||||
|
||||
void FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, int y)
|
||||
{
|
||||
if(!alloc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *text = (const char *)alloc->getPtr();
|
||||
size_t allocSize = alloc->getType()->getSizeBytes();
|
||||
renderText(text, allocSize, start, len, x, y);
|
||||
void FontState::measureText(const char *text, uint32_t len, Font::Rect *bounds) {
|
||||
renderText(text, len, 0, 0, 0, -1, Font::MEASURE, bounds);
|
||||
}
|
||||
|
||||
void FontState::setFontColor(float r, float g, float b, float a) {
|
||||
@@ -773,7 +825,7 @@ void FontState::setFontColor(float r, float g, float b, float a) {
|
||||
mConstants.mFontColor[3] = a;
|
||||
|
||||
mConstants.mGamma = 1.0f;
|
||||
const int luminance = (r * 2.0f + g * 5.0f + b) / 8.0f;
|
||||
const int32_t luminance = (r * 2.0f + g * 5.0f + b) / 8.0f;
|
||||
if (luminance <= mBlackThreshold) {
|
||||
mConstants.mGamma = mBlackGamma;
|
||||
} else if (luminance >= mWhiteThreshold) {
|
||||
|
||||
@@ -45,12 +45,26 @@ class FontState;
|
||||
class Font : public ObjectBase
|
||||
{
|
||||
public:
|
||||
~Font();
|
||||
enum RenderMode {
|
||||
FRAMEBUFFER,
|
||||
BITMAP,
|
||||
MEASURE,
|
||||
};
|
||||
|
||||
// Pointer to the utf data, length of data, where to start, number of glyphs ot read
|
||||
// (each glyph may be longer than a char because we are dealing with utf data)
|
||||
// Last two variables are the initial pen position
|
||||
void renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y);
|
||||
struct Rect {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
void set(int32_t l, int32_t r, int32_t t, int32_t b) {
|
||||
left = l;
|
||||
right = r;
|
||||
top = t;
|
||||
bottom = b;
|
||||
}
|
||||
};
|
||||
|
||||
~Font();
|
||||
|
||||
// Currently files do not get serialized,
|
||||
// but we need to inherit from ObjectBase for ref tracking
|
||||
@@ -66,6 +80,14 @@ protected:
|
||||
|
||||
friend class FontState;
|
||||
|
||||
// Pointer to the utf data, length of data, where to start, number of glyphs ot read
|
||||
// (each glyph may be longer than a char because we are dealing with utf data)
|
||||
// Last two variables are the initial pen position
|
||||
void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
|
||||
uint32_t start, int32_t numGlyphs,
|
||||
RenderMode mode = FRAMEBUFFER, Rect *bounds = NULL,
|
||||
uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
|
||||
|
||||
void invalidateTextureCache();
|
||||
struct CachedGlyphInfo
|
||||
{
|
||||
@@ -106,7 +128,10 @@ protected:
|
||||
|
||||
CachedGlyphInfo *cacheGlyph(uint32_t glyph);
|
||||
void updateGlyphCache(CachedGlyphInfo *glyph);
|
||||
void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
|
||||
void measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds);
|
||||
void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y);
|
||||
void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y,
|
||||
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
|
||||
};
|
||||
|
||||
class FontState
|
||||
@@ -121,10 +146,13 @@ public:
|
||||
ObjectBaseRef<Font> mDefault;
|
||||
ObjectBaseRef<Font> mLast;
|
||||
|
||||
void renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y);
|
||||
void renderText(const char *text, int x, int y);
|
||||
void renderText(Allocation *alloc, int x, int y);
|
||||
void renderText(Allocation *alloc, uint32_t start, int len, int x, int y);
|
||||
void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
|
||||
uint32_t startIndex = 0, int numGlyphs = -1,
|
||||
Font::RenderMode mode = Font::FRAMEBUFFER,
|
||||
Font::Rect *bounds = NULL,
|
||||
uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
|
||||
|
||||
void measureText(const char *text, uint32_t len, Font::Rect *bounds);
|
||||
|
||||
void setFontColor(float r, float g, float b, float a);
|
||||
void getFontColor(float *r, float *g, float *b, float *a) const;
|
||||
@@ -198,6 +226,9 @@ protected:
|
||||
// Texture to cache glyph bitmaps
|
||||
ObjectBaseRef<Allocation> mTextTexture;
|
||||
void initTextTexture();
|
||||
const uint8_t* getTextTextureData() const {
|
||||
return (uint8_t*)mTextTexture->getPtr();
|
||||
}
|
||||
|
||||
bool cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
|
||||
const Type* getCacheTextureType() {
|
||||
|
||||
@@ -351,13 +351,59 @@ static void SC_DrawTextAlloc(RsAllocation va, int x, int y)
|
||||
CHECK_OBJ(va);
|
||||
GET_TLS();
|
||||
Allocation *alloc = static_cast<Allocation *>(va);
|
||||
rsc->mStateFont.renderText(alloc, x, y);
|
||||
const char *text = (const char *)alloc->getPtr();
|
||||
size_t allocSize = alloc->getType()->getSizeBytes();
|
||||
rsc->mStateFont.renderText(text, allocSize, x, y);
|
||||
}
|
||||
|
||||
static void SC_DrawText(const char *text, int x, int y)
|
||||
{
|
||||
GET_TLS();
|
||||
rsc->mStateFont.renderText(text, x, y);
|
||||
size_t textLen = strlen(text);
|
||||
rsc->mStateFont.renderText(text, textLen, x, y);
|
||||
}
|
||||
|
||||
static void SC_setMetrics(Font::Rect *metrics,
|
||||
int32_t *left, int32_t *right,
|
||||
int32_t *top, int32_t *bottom)
|
||||
{
|
||||
if(left) {
|
||||
*left = metrics->left;
|
||||
}
|
||||
if(right) {
|
||||
*right = metrics->right;
|
||||
}
|
||||
if(top) {
|
||||
*top = metrics->top;
|
||||
}
|
||||
if(bottom) {
|
||||
*bottom = metrics->bottom;
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_MeasureTextAlloc(RsAllocation va,
|
||||
int32_t *left, int32_t *right,
|
||||
int32_t *top, int32_t *bottom)
|
||||
{
|
||||
CHECK_OBJ(va);
|
||||
GET_TLS();
|
||||
Allocation *alloc = static_cast<Allocation *>(va);
|
||||
const char *text = (const char *)alloc->getPtr();
|
||||
size_t textLen = alloc->getType()->getSizeBytes();
|
||||
Font::Rect metrics;
|
||||
rsc->mStateFont.measureText(text, textLen, &metrics);
|
||||
SC_setMetrics(&metrics, left, right, top, bottom);
|
||||
}
|
||||
|
||||
static void SC_MeasureText(const char *text,
|
||||
int32_t *left, int32_t *right,
|
||||
int32_t *top, int32_t *bottom)
|
||||
{
|
||||
GET_TLS();
|
||||
size_t textLen = strlen(text);
|
||||
Font::Rect metrics;
|
||||
rsc->mStateFont.measureText(text, textLen, &metrics);
|
||||
SC_setMetrics(&metrics, left, right, top, bottom);
|
||||
}
|
||||
|
||||
static void SC_BindFont(RsFont font)
|
||||
@@ -432,6 +478,8 @@ static ScriptCState::SymbolTable_t gSyms[] = {
|
||||
|
||||
{ "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText },
|
||||
{ "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc },
|
||||
{ "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText },
|
||||
{ "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc },
|
||||
|
||||
{ "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont },
|
||||
{ "_Z12rsgFontColorffff", (void *)&SC_FontColor },
|
||||
|
||||
@@ -79,6 +79,12 @@ extern void __attribute__((overloadable))
|
||||
rsgBindFont(rs_font);
|
||||
extern void __attribute__((overloadable))
|
||||
rsgFontColor(float, float, float, float);
|
||||
// Returns the bounding box of the text relative to (0, 0)
|
||||
// Any of left, right, top, bottom could be NULL
|
||||
extern void __attribute__((overloadable))
|
||||
rsgMeasureText(const char *, int *left, int *right, int *top, int *bottom);
|
||||
extern void __attribute__((overloadable))
|
||||
rsgMeasureText(rs_allocation, int *left, int *right, int *top, int *bottom);
|
||||
|
||||
extern void __attribute__((overloadable))
|
||||
rsgMeshComputeBoundingBox(rs_mesh mesh, float *minX, float *minY, float *minZ,
|
||||
|
||||
Reference in New Issue
Block a user