mobile/android/base/gfx/NinePatchTileLayer.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.gfx;
     8 import android.graphics.RectF;
     9 import android.opengl.GLES20;
    11 import java.nio.FloatBuffer;
    13 /**
    14  * Encapsulates the logic needed to draw a nine-patch bitmap using OpenGL ES.
    15  *
    16  * For more information on nine-patch bitmaps, see the following document:
    17  *   http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
    18  */
    19 public class NinePatchTileLayer extends TileLayer {
    20     private static final int PATCH_SIZE = 16;
    21     private static final int TEXTURE_SIZE = 64;
    23     public NinePatchTileLayer(CairoImage image) {
    24         super(image, TileLayer.PaintMode.NORMAL);
    25     }
    27     @Override
    28     public void draw(RenderContext context) {
    29         if (!initialized())
    30             return;
    32         GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    33         GLES20.glEnable(GLES20.GL_BLEND);
    35         GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    36         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
    37         drawPatches(context);
    38     }
    40     private void drawPatches(RenderContext context) {
    41         /*
    42          * We divide the nine-patch bitmap up as follows:
    43          *
    44          *    +---+---+---+
    45          *    | 0 | 1 | 2 |
    46          *    +---+---+---+
    47          *    | 3 |   | 4 |
    48          *    +---+---+---+
    49          *    | 5 | 6 | 7 |
    50          *    +---+---+---+
    51          */
    53         // page is the rect of the "missing" center spot in the picture above
    54         RectF page = context.pageRect;
    56         drawPatch(context, 0, PATCH_SIZE * 3,                                              /* 0 */
    57                   page.left - PATCH_SIZE, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
    58         drawPatch(context, PATCH_SIZE, PATCH_SIZE * 3,                                     /* 1 */
    59                   page.left, page.top - PATCH_SIZE, page.width(), PATCH_SIZE);
    60         drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 3,                                 /* 2 */
    61                   page.right, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
    62         drawPatch(context, 0, PATCH_SIZE * 2,                                              /* 3 */
    63                   page.left - PATCH_SIZE, page.top, PATCH_SIZE, page.height());
    64         drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2,                                 /* 4 */
    65                   page.right, page.top, PATCH_SIZE, page.height());
    66         drawPatch(context, 0, PATCH_SIZE,                                                  /* 5 */
    67                   page.left - PATCH_SIZE, page.bottom, PATCH_SIZE, PATCH_SIZE);
    68         drawPatch(context, PATCH_SIZE, PATCH_SIZE,                                         /* 6 */
    69                   page.left, page.bottom, page.width(), PATCH_SIZE);
    70         drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE,                                     /* 7 */
    71                   page.right, page.bottom, PATCH_SIZE, PATCH_SIZE);
    72     }
    74     private void drawPatch(RenderContext context, int textureX, int textureY,
    75                            float tileX, float tileY, float tileWidth, float tileHeight) {
    76         RectF viewport = context.viewport;
    77         float viewportHeight = viewport.height();
    78         float drawX = tileX - viewport.left - context.offset.x;
    79         float drawY = viewportHeight - (tileY + tileHeight - viewport.top) - context.offset.y;
    81         float[] coords = {
    82             //x, y, z, texture_x, texture_y
    83             drawX/viewport.width(), drawY/viewport.height(), 0,
    84             textureX/(float)TEXTURE_SIZE, textureY/(float)TEXTURE_SIZE,
    86             drawX/viewport.width(), (drawY+tileHeight)/viewport.height(), 0,
    87             textureX/(float)TEXTURE_SIZE, (textureY+PATCH_SIZE)/(float)TEXTURE_SIZE,
    89             (drawX+tileWidth)/viewport.width(), drawY/viewport.height(), 0,
    90             (textureX+PATCH_SIZE)/(float)TEXTURE_SIZE, textureY/(float)TEXTURE_SIZE,
    92             (drawX+tileWidth)/viewport.width(), (drawY+tileHeight)/viewport.height(), 0,
    93             (textureX+PATCH_SIZE)/(float)TEXTURE_SIZE, (textureY+PATCH_SIZE)/(float)TEXTURE_SIZE
    95         };
    97         // Get the buffer and handles from the context
    98         FloatBuffer coordBuffer = context.coordBuffer;
    99         int positionHandle = context.positionHandle;
   100         int textureHandle = context.textureHandle;
   102         // Make sure we are at position zero in the buffer in case other draw methods did not clean
   103         // up after themselves
   104         coordBuffer.position(0);
   105         coordBuffer.put(coords);
   107         // Unbind any the current array buffer so we can use client side buffers
   108         GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
   110         // Vertex coordinates are x,y,z starting at position 0 into the buffer.
   111         coordBuffer.position(0);
   112         GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
   114         // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
   115         coordBuffer.position(3);
   116         GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
   118         GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
   119                                GLES20.GL_CLAMP_TO_EDGE);
   120         GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
   121                                GLES20.GL_CLAMP_TO_EDGE);
   123         // Use bilinear filtering for both magnification and minimization of the texture. This
   124         // applies only to the shadow layer so we do not incur a high overhead.
   125         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
   126                                GLES20.GL_LINEAR);
   127         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
   128                                GLES20.GL_LINEAR);
   130         GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
   131     }
   132 }

mercurial