support lcd16 in text atlas (sans shader support)



git-svn-id: http://skia.googlecode.com/svn/trunk@939 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index b55a029..ea32719 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -51,7 +51,7 @@
     static int gCounter;
 #endif
 
-GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY) {
+GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) {
     fAtlasMgr = mgr;    // just a pointer, not an owner
     fNext = NULL;
     fTexture = mgr->getTexture(); // we're not an owner, just a pointer
@@ -60,6 +60,8 @@
     fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
                                    GR_ATLAS_HEIGHT - BORDER);
 
+    fMaskFormat = format;
+
 #if GR_DEBUG
     GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
     gCounter += 1;
@@ -82,6 +84,13 @@
     loc->fY += plot.fY * GR_ATLAS_HEIGHT;
 }
 
+static uint8_t* zerofill(uint8_t* ptr, int count) {
+    while (--count >= 0) {
+        *ptr++ = 0;
+    }
+    return ptr;
+}
+
 bool GrAtlas::addSubImage(int width, int height, const void* image,
                           GrIPoint16* loc) {
     if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
@@ -89,23 +98,26 @@
     }
 
     GrAutoSMalloc<1024> storage;
-    int srcW = width + 2*BORDER;
-    int srcH = height + 2*BORDER;
+    int dstW = width + 2*BORDER;
+    int dstH = height + 2*BORDER;
     if (BORDER) {
-        uint8_t* ptr = (uint8_t*)storage.realloc(srcW * srcH);
-        Gr_bzero(ptr, srcW);                // zero top row
-        ptr += srcW;
+        const int bpp = GrMaskFormatBytesPerPixel(fMaskFormat);
+        const size_t dstRB = dstW * bpp;
+        uint8_t* dst = (uint8_t*)storage.realloc(dstH * dstRB);
+        Gr_bzero(dst, dstRB);                // zero top row
+        dst += dstRB;
         for (int y = 0; y < height; y++) {
-            *ptr++ = 0;                     // zero left edge
-            memcpy(ptr, image, width); ptr += width;
-            *ptr++ = 0;                     // zero right edge
-            image = (const void*)((const char*)image + width);
+            dst = zerofill(dst, bpp);   // zero left edge
+            memcpy(dst, image, width * bpp);
+            dst += width * bpp;
+            dst = zerofill(dst, bpp);   // zero right edge
+            image = (const void*)((const char*)image + width * bpp);
         }
-        Gr_bzero(ptr, srcW);                // zero bottom row
+        Gr_bzero(dst, dstRB);                // zero bottom row
         image = storage.get();
     }
     adjustForPlot(loc, fPlot);
-    fTexture->uploadTextureData(loc->fX, loc->fY, srcW, srcH, image);
+    fTexture->uploadTextureData(loc->fX, loc->fY, dstW, dstH, image);
 
     // now tell the caller to skip the top/left BORDER
     loc->fX += BORDER;
@@ -128,9 +140,23 @@
     fGpu->unref();
 }
 
+static GrTexture::PixelConfig maskformat2pixelconfig(GrMaskFormat format) {
+    switch (format) {
+        case kA8_GrMaskFormat:
+            return GrTexture::kAlpha_8_PixelConfig;
+        case kA565_GrMaskFormat:
+            return GrTexture::kRGB_565_PixelConfig;
+        default:
+            GrAssert(!"unknown maskformat");
+    }
+    return GrTexture::kUnknown_PixelConfig;
+}
+
 GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
                                 int width, int height, const void* image,
+                                GrMaskFormat format,
                                 GrIPoint16* loc) {
+    GrAssert(NULL == atlas || atlas->getMaskFormat() == format);
     if (atlas && atlas->addSubImage(width, height, image, loc)) {
         return atlas;
     }
@@ -145,11 +171,11 @@
 
     if (NULL == fTexture) {
         GrGpu::TextureDesc desc = {
-            GrGpu::kDynamicUpdate_TextureFlag, 
+            GrGpu::kDynamicUpdate_TextureFlag,
             GrGpu::kNone_AALevel,
-            GR_ATLAS_TEXTURE_WIDTH, 
+            GR_ATLAS_TEXTURE_WIDTH,
             GR_ATLAS_TEXTURE_HEIGHT,
-            GrTexture::kAlpha_8_PixelConfig
+            maskformat2pixelconfig(format)
         };
         fTexture = fGpu->createTexture(desc, NULL, 0);
         if (NULL == fTexture) {
@@ -157,7 +183,7 @@
         }
     }
 
-    GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY);
+    GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY, format);
     if (!newAtlas->addSubImage(width, height, image, loc)) {
         delete newAtlas;
         return NULL;
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
index c2d81d5..6cdb61c 100644
--- a/gpu/src/GrTextStrike.cpp
+++ b/gpu/src/GrTextStrike.cpp
@@ -41,7 +41,8 @@
     if (NULL == fAtlasMgr) {
         fAtlasMgr = new GrAtlasMgr(fGpu);
     }
-    GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(), fAtlasMgr);
+    GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(),
+                                            scaler->getMaskFormat(), fAtlasMgr);
     fCache.insert(key, strike);
 
     if (fHead) {
@@ -131,6 +132,7 @@
  */
 
 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
+                           GrMaskFormat format,
                            GrAtlasMgr* atlasMgr) : fPool(64) {
     fFontScalerKey = key;
     fFontScalerKey->ref();
@@ -139,6 +141,8 @@
     fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
     fAtlas = NULL;
 
+    fMaskFormat = format;
+
 #if GR_DEBUG
     GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
     gCounter += 1;
@@ -180,17 +184,20 @@
     }
 
     GrAutoRef ar(scaler);
-    
-    size_t size = glyph->fBounds.area();
+
+    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
+    size_t size = glyph->fBounds.area() * bytesPerPixel;
     GrAutoSMalloc<1024> storage(size);
     if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
-                                     glyph->height(), glyph->width(),
+                                     glyph->height(),
+                                     glyph->width() * bytesPerPixel,
                                      storage.get())) {
         return false;
     }
 
     GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
                                            glyph->height(), storage.get(),
+                                           fMaskFormat,
                                            &glyph->fAtlasLocation);
     if (NULL == atlas) {
         return false;