Android PdfDocument 上的坐标和裁剪
Coordinates and clipping on Android PdfDocument
我一直很高兴地在 Android PDF class PdfDocument 中生成 PDF 文档。在对 "subtle" 文档感到困惑之后,我推测坐标系是在 PostScript (1/72")
中
private static final int A4_WIDTH = 595;
private static final int A4_HEIGHT = 842;
private static final int CM = 28;
private static final int footer_height = CM;
void startPage() {
if (currentPage != null) {
finishPage(currentPage);
}
PageInfo.Builder pageBuilder = new PageInfo.Builder(A4_WIDTH, A4_HEIGHT, page++);
Rect rect = new Rect(0, 0, A4_WIDTH, A4_HEIGHT);
rect.inset(CM, 2 * CM);
pageBuilder.setContentRect(rect);
PageInfo pageInfo = pageBuilder.create();
pagePosition = 0.0f;
pageWidth = rect.width();
pageHeight = rect.height();
currentPage = super.startPage(pageInfo);
page_count++;
if (has_footer)
putFooter();
}
这在我的 Nexus 10 上运行良好,但我很惊讶在三星 S6 上坐标系似乎乱七八糟,所以在 Nexus 10 上我将文本放在 0,0 处,它很适合向下 2 厘米,横向 1 厘米,但在 S6 上,它看起来向下 4 厘米,横向 2 厘米。此外,底部和右侧被裁剪了 2 厘米和 1 厘米。换句话说,裁剪矩形在正确的位置,但坐标系似乎被双重偏移了。
我的绘制代码如下所示:
canvas.save();
canvas.translate(0, pagePosition);
staticLayout.draw(canvas);
canvas.restore();
其中 pagePosition 是一个简单的 ps 计数器,由 staticLayout.getHeight();
的结果测量文本驱动
需要说明的是,在相当复杂的文本、线条图和图像组合上,布局非常准确,没有任何缺陷,只是遇到了这个与设备相关的缺陷。
Bug 还是我的大脑?
编辑:左边是 Nexus,右边是 S6
生成代码:
import android.annotation.TargetApi;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.pdf.PdfDocument;
import android.support.v4.content.ContextCompat;
import uk.co.spennycycles.pocketcycletech.PocketCycleTechApp;
import uk.co.spennycycles.pocketcycletech.R;
@TargetApi(19)
public class TestReport extends PdfDocument {
private static final String TAG = SpennyPdfDocument.class.getSimpleName();
private static final int A4_WIDTH = 595;
private static final int A4_HEIGHT = 842;
private static final int CM = 28;
int pageWidth;
int pageHeight;
public void generateReport() {
PageInfo.Builder pageBuilder = new PageInfo.Builder(A4_WIDTH, A4_HEIGHT, 1);
Rect rect = new Rect(0, 0, A4_WIDTH, A4_HEIGHT);
rect.inset(CM, 2 * CM);
pageBuilder.setContentRect(rect);
PageInfo pageInfo = pageBuilder.create();
Page page = super.startPage(pageInfo);
pageWidth = rect.width();
pageHeight = rect.height();
Canvas canvas = page.getCanvas();
RectF r = new RectF((float) 0, 0, pageWidth, pageHeight);
r.inset(1.0f, 1.0f);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(ContextCompat.getColor(PocketCycleTechApp.getContext(), R.color.lt_gray));
canvas.drawRect(r, paint);
paint.setColor(ContextCompat.getColor(PocketCycleTechApp.getContext(), R.color.black));
paint.setStrokeWidth(2.0f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(r, paint);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(r.left, r.top, r.right, r.bottom, paint);
canvas.drawLine(r.right, r.top, r.left, r.bottom, paint);
finishPage(page);
}
}
解决方法:
currentPage = super.startPage(pageInfo);
Canvas canvas = currentPage.getCanvas();
canvas.translate(CM, CM*2);
canvas.clipRect(0, 0, rect.width(), rect.height());
使 canvas 处于完全相同的状态。
我一直很高兴地在 Android PDF class PdfDocument 中生成 PDF 文档。在对 "subtle" 文档感到困惑之后,我推测坐标系是在 PostScript (1/72")
中private static final int A4_WIDTH = 595;
private static final int A4_HEIGHT = 842;
private static final int CM = 28;
private static final int footer_height = CM;
void startPage() {
if (currentPage != null) {
finishPage(currentPage);
}
PageInfo.Builder pageBuilder = new PageInfo.Builder(A4_WIDTH, A4_HEIGHT, page++);
Rect rect = new Rect(0, 0, A4_WIDTH, A4_HEIGHT);
rect.inset(CM, 2 * CM);
pageBuilder.setContentRect(rect);
PageInfo pageInfo = pageBuilder.create();
pagePosition = 0.0f;
pageWidth = rect.width();
pageHeight = rect.height();
currentPage = super.startPage(pageInfo);
page_count++;
if (has_footer)
putFooter();
}
这在我的 Nexus 10 上运行良好,但我很惊讶在三星 S6 上坐标系似乎乱七八糟,所以在 Nexus 10 上我将文本放在 0,0 处,它很适合向下 2 厘米,横向 1 厘米,但在 S6 上,它看起来向下 4 厘米,横向 2 厘米。此外,底部和右侧被裁剪了 2 厘米和 1 厘米。换句话说,裁剪矩形在正确的位置,但坐标系似乎被双重偏移了。
我的绘制代码如下所示:
canvas.save();
canvas.translate(0, pagePosition);
staticLayout.draw(canvas);
canvas.restore();
其中 pagePosition 是一个简单的 ps 计数器,由 staticLayout.getHeight();
的结果测量文本驱动需要说明的是,在相当复杂的文本、线条图和图像组合上,布局非常准确,没有任何缺陷,只是遇到了这个与设备相关的缺陷。
Bug 还是我的大脑?
编辑:左边是 Nexus,右边是 S6
生成代码:
import android.annotation.TargetApi;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.pdf.PdfDocument;
import android.support.v4.content.ContextCompat;
import uk.co.spennycycles.pocketcycletech.PocketCycleTechApp;
import uk.co.spennycycles.pocketcycletech.R;
@TargetApi(19)
public class TestReport extends PdfDocument {
private static final String TAG = SpennyPdfDocument.class.getSimpleName();
private static final int A4_WIDTH = 595;
private static final int A4_HEIGHT = 842;
private static final int CM = 28;
int pageWidth;
int pageHeight;
public void generateReport() {
PageInfo.Builder pageBuilder = new PageInfo.Builder(A4_WIDTH, A4_HEIGHT, 1);
Rect rect = new Rect(0, 0, A4_WIDTH, A4_HEIGHT);
rect.inset(CM, 2 * CM);
pageBuilder.setContentRect(rect);
PageInfo pageInfo = pageBuilder.create();
Page page = super.startPage(pageInfo);
pageWidth = rect.width();
pageHeight = rect.height();
Canvas canvas = page.getCanvas();
RectF r = new RectF((float) 0, 0, pageWidth, pageHeight);
r.inset(1.0f, 1.0f);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(ContextCompat.getColor(PocketCycleTechApp.getContext(), R.color.lt_gray));
canvas.drawRect(r, paint);
paint.setColor(ContextCompat.getColor(PocketCycleTechApp.getContext(), R.color.black));
paint.setStrokeWidth(2.0f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(r, paint);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(r.left, r.top, r.right, r.bottom, paint);
canvas.drawLine(r.right, r.top, r.left, r.bottom, paint);
finishPage(page);
}
}
解决方法:
currentPage = super.startPage(pageInfo);
Canvas canvas = currentPage.getCanvas();
canvas.translate(CM, CM*2);
canvas.clipRect(0, 0, rect.width(), rect.height());
使 canvas 处于完全相同的状态。