start rewriting rollo so it's a little more parameterized.

This commit is contained in:
Joe Onorato 2009-08-08 18:53:53 -07:00
parent bf15cb44cc
commit 43e7bcf0ad
6 changed files with 467 additions and 156 deletions

View File

@ -3,10 +3,22 @@
#pragma stateFragment(PF)
#pragma stateFragmentStore(PFS)
// Scratch buffer layout
#define SCRATCH_FADE 0
#define SCRATCH_ZOOM 1
#define SCRATCH_ROT 2
#define PI 3.14159f
// Allocations ======
#define ALLOC_PARAMS 0
#define ALLOC_STATE 1
#define ALLOC_SCRATCH 2
#define ALLOC_ICON_IDS 3
#define ALLOC_LABEL_IDS 4
// Variables from java ======
// Parameters ======
#define PARAM_BUBBLE_WIDTH 0
#define PARAM_BUBBLE_HEIGHT 1
#define PARAM_BUBBLE_BITMAP_WIDTH 2
#define PARAM_BUBBLE_BITMAP_HEIGHT 3
//#define STATE_POS_X 0
#define STATE_DONE 1
@ -19,166 +31,124 @@
#define STATE_COUNT 8
#define STATE_TOUCH 9
// Scratch variables ======
#define SCRATCH_FADE 0
#define SCRATCH_ZOOM 1
#define SCRATCH_ROT 2
float filter(float val, float target, float str)
// Drawing constants, should be parameters ======
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 854
#define COLUMNS_PER_PAGE 4
#define ROWS_PER_PAGE 4
#define DIAMETER 8.0f
#define PAGE_PADDING_TOP_PX 80
#define CELL_PADDING_TOP_PX 5
#define ICON_HEIGHT_PX 64
#define ICON_LABEL_GUTTER_PX 5
#define CELL_PADDING_BOTTOM_PX 5
#define ROW_GUTTER_PX 10
#define PAGE_PADDING_LEFT_PX 22
#define CELL_WIDTH_PX 105
#define ICON_WIDTH_PX 64
#define COLUMN_GUTTER_PX 5
#define LABEL_WIDTH_PX 105
int
count_pages(int iconCount)
{
float delta = (target - val);
return val + delta * str;
int iconsPerPage = COLUMNS_PER_PAGE * ROWS_PER_PAGE;
int pages = iconCount / iconsPerPage;
if (pages*iconsPerPage != iconCount) {
iconCount++;
}
return iconCount;
}
int main(void* con, int ft, int launchID)
int
main(void* con, int ft, int launchID)
{
int rowCount;
int row;
int col;
int imageID;
int done = loadI32(0, STATE_DONE);
int selectedID = loadI32(0, STATE_SELECTION);
float f = loadF(2, 0);
// Clear to transparent
pfClearColor(0.0f, 0.0f, 0.0f, 0.0f);
if (done) {
if (f > 0.02f) {
//f = f - 0.02f;
//storeF(2, 0, f);
}
} else {
if (f < 0.8f) {
f = f + 0.02f;
storeF(2, 0, f);
}
}
float touchCut = 1.f;
if (loadI32(0, STATE_TOUCH)) {
touchCut = 4.f;
}
// icons & labels
int iconCount = loadI32(ALLOC_STATE, STATE_COUNT);
int pageCount = count_pages(iconCount);
float densityScale = 2.0f / SCREEN_WIDTH;
float screenTop = SCREEN_HEIGHT/(float)SCREEN_WIDTH; // == (SCREEN_HEIGHT/2)*densityScale;
float pagePaddingTop = screenTop - (PAGE_PADDING_TOP_PX * densityScale);
float pageGutterY = ROW_GUTTER_PX * densityScale;
float cellHeight = (CELL_PADDING_TOP_PX + ICON_HEIGHT_PX + ICON_LABEL_GUTTER_PX
+ loadI32(ALLOC_PARAMS, PARAM_BUBBLE_HEIGHT)
+ CELL_PADDING_BOTTOM_PX + ROW_GUTTER_PX) * densityScale;
float cellPaddingTop = CELL_PADDING_TOP_PX * densityScale;
float iconHeight = ICON_HEIGHT_PX * densityScale;
float iconLabelGutter = ICON_LABEL_GUTTER_PX * densityScale;
float pagePaddingLeft = PAGE_PADDING_LEFT_PX * densityScale;
float cellWidth = CELL_WIDTH_PX * densityScale;
float iconWidth = ICON_WIDTH_PX * densityScale;
float columnGutter = COLUMN_GUTTER_PX * densityScale;
float pageLeft = -1;
int icon = 0;
int page;
float labelWidth = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_WIDTH) * densityScale;
float labelTextureWidth = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_WIDTH) * densityScale;
float labelTextureHeight = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_HEIGHT) * densityScale;
int scrollXPx = 100;
pageLeft -= scrollXPx * densityScale;
float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f;
float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut);
storeF(2, SCRATCH_ZOOM, zoom);
for (page=0; page<pageCount; page++) {
// Bug makes 1.0f alpha fail.
color(1.0f, 1.0f, 1.0f, 0.99f);
float cellTop = pagePaddingTop;
int row;
for (row=0; row<ROWS_PER_PAGE && icon<iconCount; row++) {
float s = pageLeft; // distance along the linear strip of icons in normalized coords
s += pagePaddingLeft;
int col;
for (col=0; col<COLUMNS_PER_PAGE && icon<iconCount; col++) {
// icon
float iconLeft = s + ((cellWidth-iconWidth)/2.0f);
float iconRight = iconLeft + iconWidth;
float iconTop = cellTop - cellPaddingTop;
float iconBottom = iconTop - iconHeight;
float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f;
targetRot = targetRot * 0.80f - .12f;
float drawRot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut);
storeF(2, SCRATCH_ROT, drawRot);
bindProgramFragment(NAMED_PF);
bindProgramFragmentStore(NAMED_PFS);
float diam = 8.f;
float scale = 1.0f / zoom;
bindTexture(NAMED_PF, 0, loadI32(ALLOC_ICON_IDS, icon));
drawRect(iconLeft, iconTop, iconRight, iconBottom, 0.0f);
// Bug makes 1.0f alpha fail.
color(1.0f, 1.0f, 1.0f, 0.99f);
// label
float labelLeft = s + ((cellWidth-labelWidth)/2.0f);
float labelTop = iconBottom - iconLabelGutter;
float rot = drawRot * scale;
float rotStep = 16.0f / 180.0f * 3.14f * scale;
rowCount = 4;
int index = 0;
int iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
float tmpSin = sinf(rot);
float tmpCos = cosf(rot);
//debugF("rot", rot);
bindProgramFragment(NAMED_PFText);
bindProgramFragmentStore(NAMED_PFSText);
float tx1 = tmpSin * diam - (tmpCos * scale * 0.9f);
float tx2 = tx1 + (tmpCos * scale * 1.8f);
float tz1 = tmpCos * diam + (tmpSin * scale * 0.9f);
float tz2 = tz1 - (tmpSin * scale * 1.8f);
bindTexture(NAMED_PFText, 0, loadI32(ALLOC_LABEL_IDS, icon));
drawRect(labelLeft, labelTop, labelLeft+labelTextureWidth,
labelTop-labelTextureHeight, 0.0f);
int y;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
float ty1 = ((y * 3.1f) - 5.f) * scale;
float ty2 = ty1 + scale * 1.8f;
bindTexture(NAMED_PF, 0, loadI32(1, index));
drawQuad(tx1, ty1, tz1,
tx2, ty1, tz2,
tx2, ty2, tz2,
tx1, ty2, tz1);
iconCount--;
index++;
}
rot = rot + rotStep;
}
if ((zoom < 1.1f) && (zoom > 0.9f)) {
bindProgramVertex(NAMED_PVOrtho);
bindProgramFragment(NAMED_PFText);
bindProgramFragmentStore(NAMED_PFSText);
rot = drawRot * scale;
index = 0;
iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
int y;
float tx = 240.f + floorf(sinf(rot) * 430.f) - 64.f + 16.f;
float alpha = 2.4f - (fabsf(tx - 240.f + 48.f) / 76.f);
if (alpha > 0.99f) {
alpha = 0.99f;
s += cellWidth + columnGutter;
icon++;
}
alpha = alpha * (1.f - (fabsf(zoom - 1.f) * 10.f));
tx = tx + 0.25f;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
if (alpha > 0) {
color(1.0f, 1.0f, 1.0f, alpha);
float ty = 654.f - y * 150.f;
ty = ty + 0.25f;
bindTexture(NAMED_PFText, 0, loadI32(3, index));
drawRect(tx, ty, tx + 128.f, ty + 64.f, 0.5f);
}
iconCount--;
index++;
}
rot = rot + rotStep;
cellTop -= cellHeight;
}
bindProgramVertex(NAMED_PV);
bindProgramFragment(NAMED_PF);
bindProgramFragmentStore(NAMED_PFS);
pageLeft += 2.0f;
}
// Draw the selected icon
color(1.0f, 1.0f, 1.0f, 0.9f);
rot = drawRot * scale;
index = 0;
iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
int y;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
if (index == selectedID) {
float tmpSin = sinf(rot) * scale;
float tmpCos = cosf(rot) * scale;
float tx1 = tmpSin * diam * 0.9f - tmpCos * 2.f;
float tx2 = tx1 + (tmpCos * 4.f);
float tz1 = tmpCos * diam * 0.9f + tmpSin * 2.f;
float tz2 = tz1 - (tmpSin * 4.f);
float ty1 = ((y * 3.1f) - 4.5f) * scale;
float ty2 = ty1 + scale * 4.f;
bindTexture(NAMED_PF, 0, loadI32(1, index));
drawQuad(tx1, ty1, tz1,
tx2, ty1, tz2,
tx2, ty2, tz2,
tx1, ty2, tz1);
}
iconCount--;
index++;
}
rot = rot + rotStep;
}
return 1;
return 0;
}

184
rollo-old.c Normal file
View File

@ -0,0 +1,184 @@
#pragma version(1)
#pragma stateVertex(PV)
#pragma stateFragment(PF)
#pragma stateFragmentStore(PFS)
// Scratch buffer layout
#define SCRATCH_FADE 0
#define SCRATCH_ZOOM 1
#define SCRATCH_ROT 2
//#define STATE_POS_X 0
#define STATE_DONE 1
//#define STATE_PRESSURE 2
#define STATE_ZOOM 3
//#define STATE_WARP 4
#define STATE_ORIENTATION 5
#define STATE_SELECTION 6
#define STATE_FIRST_VISIBLE 7
#define STATE_COUNT 8
#define STATE_TOUCH 9
float filter(float val, float target, float str)
{
float delta = (target - val);
return val + delta * str;
}
int main(void* con, int ft, int launchID)
{
int rowCount;
int row;
int col;
int imageID;
int done = loadI32(0, STATE_DONE);
int selectedID = loadI32(0, STATE_SELECTION);
float f = loadF(2, 0);
pfClearColor(0.0f, 0.0f, 0.0f, 0.0f);
if (done) {
if (f > 0.02f) {
//f = f - 0.02f;
//storeF(2, 0, f);
}
} else {
if (f < 0.8f) {
f = f + 0.02f;
storeF(2, 0, f);
}
}
float touchCut = 1.f;
if (loadI32(0, STATE_TOUCH)) {
touchCut = 4.f;
}
float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f;
float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut);
storeF(2, SCRATCH_ZOOM, zoom);
float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f;
targetRot = targetRot * 0.80f - .12f;
float drawRot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut);
storeF(2, SCRATCH_ROT, drawRot);
float diam = 8.f;
float scale = 1.0f / zoom;
// Bug makes 1.0f alpha fail.
color(1.0f, 1.0f, 1.0f, 0.99f);
float rot = drawRot * scale;
float rotStep = 16.0f / 180.0f * 3.14f * scale;
rowCount = 4;
int index = 0;
int iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
float tmpSin = sinf(rot);
float tmpCos = cosf(rot);
//debugF("rot", rot);
float tx1 = tmpSin * diam - (tmpCos * scale * 0.9f);
float tx2 = tx1 + (tmpCos * scale * 1.8f);
float tz1 = tmpCos * diam + (tmpSin * scale * 0.9f);
float tz2 = tz1 - (tmpSin * scale * 1.8f);
int y;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
float ty1 = ((y * 3.1f) - 5.f) * scale;
float ty2 = ty1 + scale * 1.8f;
bindTexture(NAMED_PF, 0, loadI32(1, index));
drawQuad(tx1, ty1, tz1,
tx2, ty1, tz2,
tx2, ty2, tz2,
tx1, ty2, tz1);
iconCount--;
index++;
}
rot = rot + rotStep;
}
if ((zoom < 1.1f) && (zoom > 0.9f)) {
bindProgramVertex(NAMED_PVOrtho);
bindProgramFragment(NAMED_PFText);
bindProgramFragmentStore(NAMED_PFSText);
rot = drawRot * scale;
index = 0;
iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
int y;
float tx = 240.f + floorf(sinf(rot) * 430.f) - 64.f + 16.f;
float alpha = 2.4f - (fabsf(tx - 240.f + 48.f) / 76.f);
if (alpha > 0.99f) {
alpha = 0.99f;
}
alpha = alpha * (1.f - (fabsf(zoom - 1.f) * 10.f));
tx = tx + 0.25f;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
if (alpha > 0) {
color(1.0f, 1.0f, 1.0f, alpha);
float ty = 654.f - y * 150.f;
ty = ty + 0.25f;
bindTexture(NAMED_PFText, 0, loadI32(3, index));
drawRect(tx, ty, tx + 128.f, ty + 64.f, 0.5f);
}
iconCount--;
index++;
}
rot = rot + rotStep;
}
bindProgramVertex(NAMED_PV);
bindProgramFragment(NAMED_PF);
bindProgramFragmentStore(NAMED_PFS);
}
// Draw the selected icon
color(1.0f, 1.0f, 1.0f, 0.9f);
rot = drawRot * scale;
index = 0;
iconCount = loadI32(0, STATE_COUNT);
while (iconCount) {
int y;
for (y = rowCount -1; (y >= 0) && iconCount; y--) {
if (index == selectedID) {
float tmpSin = sinf(rot) * scale;
float tmpCos = cosf(rot) * scale;
float tx1 = tmpSin * diam * 0.9f - tmpCos * 2.f;
float tx2 = tx1 + (tmpCos * 4.f);
float tz1 = tmpCos * diam * 0.9f + tmpSin * 2.f;
float tz2 = tz1 - (tmpSin * 4.f);
float ty1 = ((y * 3.1f) - 4.5f) * scale;
float ty2 = ty1 + scale * 4.f;
bindTexture(NAMED_PF, 0, loadI32(1, index));
drawQuad(tx1, ty1, tz1,
tx2, ty1, tz2,
tx2, ty2, tz2,
tx1, ty2, tz1);
}
iconCount--;
index++;
}
rot = rot + rotStep;
}
return 1;
}

View File

@ -243,6 +243,12 @@ public class AllAppsView extends RSSurfaceView {
public static final int STATE_COUNT = 8;
public static final int STATE_TOUCH = 9;
static final int ALLOC_PARAMS = 0;
static final int ALLOC_STATE = 1;
static final int ALLOC_SCRATCH = 2;
static final int ALLOC_ICON_IDS = 3;
static final int ALLOC_LABEL_IDS = 4;
public RolloRS() {
}
@ -291,6 +297,7 @@ public class AllAppsView extends RSSurfaceView {
private Sampler mSamplerText;
private ProgramStore mPSBackground;
private ProgramStore mPSText;
private ProgramFragment mPFDebug;
private ProgramFragment mPFImages;
private ProgramFragment mPFText;
private ProgramVertex mPV;
@ -312,6 +319,18 @@ public class AllAppsView extends RSSurfaceView {
private int[] mAllocScratchBuf;
private Allocation mAllocScratch;
Params mParams;
class Params extends IntAllocation {
Params(RenderScript rs) {
super(rs);
}
@AllocationIndex(0) public int bubbleWidth;
@AllocationIndex(1) public int bubbleHeight;
@AllocationIndex(2) public int bubbleBitmapWidth;
@AllocationIndex(3) public int bubbleBitmapHeight;
}
private void initNamed() {
Sampler.Builder sb = new Sampler.Builder(mRS);
sb.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR);
@ -324,6 +343,9 @@ public class AllAppsView extends RSSurfaceView {
sb.setMag(Sampler.Value.NEAREST);
mSamplerText = sb.create();
ProgramFragment.Builder dbg = new ProgramFragment.Builder(mRS, null, null);
mPFDebug = dbg.create();
mPFDebug.setName("PFDebug");
ProgramFragment.Builder bf = new ProgramFragment.Builder(mRS, null, null);
bf.setTexEnable(true, 0);
@ -380,6 +402,8 @@ public class AllAppsView extends RSSurfaceView {
}
private void initIcons(int count) {
mParams = new Params(mRS);
mIcons = new Allocation[count];
mAllocIconIDBuf = new int[count];
mAllocIconID = Allocation.createSized(mRS,
@ -394,6 +418,12 @@ public class AllAppsView extends RSSurfaceView {
final Utilities.BubbleText bubble = new Utilities.BubbleText(getContext());
mParams.bubbleWidth = bubble.getBubbleWidth();
mParams.bubbleHeight = bubble.getMaxBubbleHeight();
mParams.bubbleBitmapWidth = bubble.getBitmapWidth();
mParams.bubbleBitmapHeight = bubble.getBitmapHeight();
mParams.save();
for (int i=0; i<count; i++) {
mIcons[i] = Allocation.createFromBitmapResource(
mRS, mRes, R.raw.maps, ie8888, true);
@ -430,10 +460,12 @@ public class AllAppsView extends RSSurfaceView {
mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0};
mAllocState = Allocation.createSized(mRS,
Element.USER_I32, mAllocStateBuf.length);
mScript.bindAllocation(mAllocState, 0);
mScript.bindAllocation(mAllocIconID, 1);
mScript.bindAllocation(mAllocScratch, 2);
mScript.bindAllocation(mAllocLabelID, 3);
mScript.bindAllocation(mParams.getAllocation(), ALLOC_PARAMS);
mScript.bindAllocation(mAllocState, ALLOC_STATE);
mScript.bindAllocation(mAllocIconID, ALLOC_ICON_IDS);
mScript.bindAllocation(mAllocScratch, ALLOC_SCRATCH);
mScript.bindAllocation(mAllocLabelID, ALLOC_LABEL_IDS);
setPosition(0);
setZoom(1);

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher2;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotate fields of a subclass of {@link IntAllocaiton} or
* FloatAllocation with this, and the save() method on those
* those classes will find the field an save it.
* <p>
* TODO: This would be even better if the allocations were
* named, and renderscript automatically added them into to
* the renderscript namespace.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface AllocationIndex {
/**
* The index in the allocation to use inside renderscript.
*/
int value();
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher2;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import java.lang.reflect.Field;
public class IntAllocation {
private RenderScript mRS;
private int[] mBuffer;
private Allocation mAlloc;
public IntAllocation(RenderScript rs) {
mRS = rs;
}
public void save() {
Field[] fields = this.getClass().getFields();
if (mBuffer == null) {
int maxIndex = 0;
for (Field f: fields) {
AllocationIndex index = f.getAnnotation(AllocationIndex.class);
if (index != null) {
int value = index.value();
if (value > maxIndex) {
maxIndex = value;
}
}
}
mBuffer = new int[maxIndex+1];
mAlloc = Allocation.createSized(mRS, Element.USER_I32, mBuffer.length);
}
int[] buf = mBuffer;
for (Field f: fields) {
AllocationIndex index = f.getAnnotation(AllocationIndex.class);
if (index != null) {
try {
buf[index.value()] = f.getInt(this);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
}
mAlloc.data(buf);
}
Allocation getAllocation() {
return mAlloc;
}
}

View File

@ -234,7 +234,7 @@ final class Utilities {
final float paddingRight = 5.0f * scale;
final float cellWidth = resources.getDimension(R.dimen.workspace_cell_width);
final float bubbleWidth = cellWidth - paddingLeft - paddingRight;
mBubblePadding = 5.0f * scale;
mBubblePadding = 3.0f * scale;
RectF bubbleRect = mBubbleRect;
bubbleRect.left = 0;
@ -245,27 +245,29 @@ final class Utilities {
mTextWidth = bubbleWidth - mBubblePadding - mBubblePadding;
Paint rectPaint = mRectPaint = new Paint();
rectPaint.setColor(0xff000000);
rectPaint.setColor(0xaa000000);
rectPaint.setAntiAlias(true);
TextPaint textPaint = mTextPaint = new TextPaint();
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setTextSize(20);
textPaint.setColor(0xffffffff);
textPaint.setAntiAlias(true);
float ascent = -textPaint.ascent();
float descent = textPaint.descent();
float leading = (ascent+descent) * 0.1f;
float leading = 0.0f;//(ascent+descent) * 0.1f;
mLeading = (int)(leading + 0.5f);
mFirstLineY = (int)(leading + ascent + 0.5f);
mLineHeight = (int)(leading + ascent + descent + 0.5f);
roundToPow2(64);
mBitmapWidth = roundToPow2((int)(mBubbleRect.width() + 0.5f));
mBitmapHeight = roundToPow2((int)((MAX_LINES * mLineHeight) + mLeading + 0.5f));
mBitmapHeight = roundToPow2((int)((MAX_LINES * mLineHeight) + leading + 0.5f));
Log.d(Launcher.LOG_TAG, "mBitmapWidth=" + mBitmapWidth + " mBitmapHeight="
+ mBitmapHeight + " w=" + ((int)(mBubbleRect.width() + 0.5f))
+ " h=" + ((int)((MAX_LINES * mLineHeight) + mLeading + 0.5f)));
+ " h=" + ((int)((MAX_LINES * mLineHeight) + leading + 0.5f)));
}
/** You own the bitmap after this and you must call recycle on it. */
@ -281,9 +283,8 @@ final class Utilities {
}
if (lineCount > 0) {
RectF bubbleRect = mBubbleRect;
bubbleRect.bottom = (int)((lineCount * mLineHeight) + mLeading + mLeading + 0.0f);
bubbleRect.bottom = height(lineCount);
c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint);
Log.d(Launcher.LOG_TAG, "bubbleRect=" + bubbleRect);
}
for (int i=0; i<lineCount; i++) {
int x = (int)((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f);
@ -294,6 +295,26 @@ final class Utilities {
return b;
}
private int height(int lineCount) {
return (int)((lineCount * mLineHeight) + mLeading + mLeading + 0.0f);
}
int getBubbleWidth() {
return (int)(mBubbleRect.width() + 0.5f);
}
int getMaxBubbleHeight() {
return height(MAX_LINES);
}
int getBitmapWidth() {
return mBitmapWidth;
}
int getBitmapHeight() {
return mBitmapHeight;
}
}
/** Only works for positive numbers. */