Esempio n. 1
0
void KPR_canvasPattern_setStyle(xsMachine *the)
{
	FskCanvas2dContext ctx = xsGetHostData(xsArg(0));
	UInt32 repetition = kFskCanvas2dPatternRepeat;
	FskConstBitmap bitmap = NULL;
	Boolean owned = false;
	xsVars(1);
	xsVar(0) = xsGet(xsThis, xsID("repetition"));
	if (xsTest(xsVar(0))) {
		xsStringValue it = xsToString(xsVar(0));
		if (!FskStrCompare(it, "no-repeat")) repetition = kFskCanvas2dPatternRepeatNone;
		else if (!FskStrCompare(it, "repeat-x")) repetition = kFskCanvas2dPatternRepeatX;
		else if (!FskStrCompare(it, "repeat-y")) repetition = kFskCanvas2dPatternRepeatY;
		else if (!FskStrCompare(it, "repeat")) repetition = kFskCanvas2dPatternRepeat;
		else xsError(kFskErrInvalidParameter);
	}
	xsVar(0) = xsGet(xsThis, xsID("image"));
	if (xsIsInstanceOf(xsVar(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID_texture))) {
		KprTexture texture = xsGetHostData(xsVar(0));
		bitmap = KprTextureGetBitmap(texture, NULL, &owned);
	}
	else {
		KprContent content = xsGetHostData(xsVar(0));
		bitmap = (*content->dispatch->getBitmap)(content, NULL, &owned);
	}
	if (!bitmap)
		xsError(kFskErrInvalidParameter);
	if (xsTest(xsArg(1)))
		FskCanvas2dSetStrokeStylePattern(ctx, repetition, bitmap);
	else
		FskCanvas2dSetFillStylePattern(ctx, repetition, bitmap);
	if (!owned)
		FskBitmapDispose((FskBitmap)bitmap);
}
Esempio n. 2
0
// drawing images
void KPR_canvasRenderingContext2D_drawImage(xsMachine *the)
{
	FskCanvas2dContext ctx = xsGetHostData(xsThis);
	xsIntegerValue c = xsToInteger(xsArgc);
	FskConstCanvas cnv = NULL;
	FskBitmap bitmap = NULL;
	Boolean owned = false;
	xsVars(1);
	if (xsIsInstanceOf(xsArg(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID_texture))) {
		KprTexture texture = xsGetHostData(xsArg(0));
		bitmap = KprTextureGetBitmap(texture, NULL, &owned);
	}
	else {
		KprContent content = xsGetHostData(xsArg(0));
		if (content->dispatch == &KprCanvasDispatchRecord)
			cnv = ((KprCanvas)content)->cnv;
		else
			bitmap = (*content->dispatch->getBitmap)(content, NULL, &owned);
	}
	if (!cnv && !bitmap)
		xsError(kFskErrInvalidParameter);
	if (c > 8) {
		xsNumberValue sx = xsToNumber(xsArg(1));
		xsNumberValue sy = xsToNumber(xsArg(2));
		xsNumberValue sw = xsToNumber(xsArg(3));
		xsNumberValue sh = xsToNumber(xsArg(4));
		xsNumberValue dx = xsToNumber(xsArg(5));
		xsNumberValue dy = xsToNumber(xsArg(6));
		xsNumberValue dw = xsToNumber(xsArg(7));
		xsNumberValue dh = xsToNumber(xsArg(8));
		if (cnv)
			FskCanvas2dDrawSubScaledCanvas2d(ctx, cnv, sx, sy, sw, sh, dx, dy, dw, dh);
		else
			FskCanvas2dDrawSubScaledBitmap(ctx, bitmap, sx, sy, sw, sh, dx, dy, dw, dh);
	}
	else if (c > 4) {
		xsNumberValue dx = xsToNumber(xsArg(1));
		xsNumberValue dy = xsToNumber(xsArg(2));
		xsNumberValue dw = xsToNumber(xsArg(3));
		xsNumberValue dh = xsToNumber(xsArg(4));
		if (cnv)
			FskCanvas2dDrawScaledCanvas2d(ctx, cnv, dx, dy, dw, dh);
		else
			FskCanvas2dDrawScaledBitmap(ctx, bitmap, dx, dy, dw, dh);
	}
	else {
		xsNumberValue dx = xsToNumber(xsArg(1));
		xsNumberValue dy = xsToNumber(xsArg(2));
		if (cnv)
			FskCanvas2dDrawCanvas2d(ctx, cnv, dx, dy);
		else
			FskCanvas2dDrawBitmap(ctx, bitmap, dx, dy);
	}
	if (!owned)
		FskBitmapDispose(bitmap);
}
Esempio n. 3
0
FskErr KplScreenDisposeBitmap(KplBitmap bitmap)
{
	FskErr err = kFskErrNone;
	KplScreen screen = gKplScreen;

	if (bitmap != screen->bitmap)
		return kFskErrOperationFailed;

	if (screen->thread) {
//		KplScreenEventWakeUp();
		FskThreadJoin(screen->thread);
		screen->thread = NULL;
	}
#if SUPPORT_FLIP_THREAD
	if (screen->flipThread) {
		KplScreenUnlockBitmap(bitmap);
		FskThreadJoin(screen->flipThread);
		screen->flipThread = NULL;
	}
#endif
	if (screen->fbfd == -1) {
		FskMemPtrDispose(screen->framebuffer);
	}
	else {
		munmap(screen->framebuffer, screen->finfo.smem_len);
		close(screen->fbfd);
	}

    FskBitmapDispose(screen->touchDown);

#if SUPPORT_FLIP_THREAD
	FskSemaphoreDispose(screen->flipSemaphore);
#endif

	FskMemPtrDispose(screen);

	terminateLinuxInput();

	gKplScreen = NULL;
	return err;
}
Esempio n. 4
0
FskErr winTextBox(FskTextEngineState state, FskBitmap bits, const char *text, UInt32 textLen, FskConstRectangle bounds, FskConstRectangleFloat boundsFloat, FskConstRectangle clipRect, FskConstColorRGBA color, UInt32 blendLevel, UInt32 textSize, UInt32 textStyle, UInt16 hAlign, UInt16 vAlign, FskFixed textExtra, const char *fontName, FskTextFormatCache formatCacheIn)
{
	FskTextFormatCacheGDI formatCache = (FskTextFormatCacheGDI)formatCacheIn;
	RECT r;
	UINT flags = DT_SINGLELINE | DT_NOPREFIX | ((kFskTextTruncateEnd & textStyle) ? DT_END_ELLIPSIS : 0);
	Boolean direct = (blendLevel >= 255) && (NULL != bits->hbmp) &&
			!((kFskTextOutline | kFskTextOutlineHeavy) & textStyle) && !bits->hasAlpha;
	FskBitmap scratchBits = NULL;
	HFONT font;
	HDC dc = direct ? bits->hdc : state->dc;
	HGDIOBJ saveFont;
	FskRectangleRecord clip;
	unsigned char scratchBuffer[256];
	int saveCharExtra;

	// combine bounds and clip to total clip
	if (NULL == clipRect) {
		clip = *bounds;
	}
	else {
		if (false == FskRectangleIntersect(clipRect, bounds, &clip))
			return kFskErrNone;
	}

	if (direct) {
		if (clipRect)
			IntersectClipRect(dc, clipRect->x, clipRect->y, clipRect->x + clipRect->width, clipRect->y + clipRect->height);
		SetRect(&r, bounds->x, bounds->y, bounds->x + bounds->width, bounds->y + bounds->height);

		SetTextColor(dc, RGB(color->r, color->g, color->b));
	}
	else {
		FskErr err;
		const UInt32 kFskTextOffscreenFormat = kFskBitmapFormat24BGR;

		/* Negative width below indicates that we want a native bitmap */
		err = FskBitmapNew(-bounds->width, bounds->height, kFskTextOffscreenFormat, &scratchBits);
		if (kFskErrNone == err)
			SetRect(&r, 0, 0, bounds->width, bounds->height);
		else {
			FskRectangleRecord b;

			err = winTextGetBounds(state, bits, text, textLen, textSize, textStyle, textExtra, fontName, &b, NULL, formatCacheIn);
			if (err) return err;

			err = FskBitmapNew(-b.width, b.height, kFskTextOffscreenFormat, &scratchBits);
			if (err) return err;

			SetRect(&r, 0, 0, b.width, b.height);
		}

		dc = scratchBits->hdc;
		SetTextColor(dc, RGB(255, 255, 255));
	}

	if (NULL == formatCache)
		saveFont = syncFont(textSize, textStyle, fontName, &font, state);
	else
		saveFont = SelectObject(dc, formatCache->font);

	saveCharExtra = SetTextCharacterExtra(dc, textExtra >> 16);

#if 0
	switch (hAlign) {
		case kFskTextAlignLeft:
		default:
			flags |= DT_LEFT;
			break;

		case kFskTextAlignCenter:
			flags |= DT_CENTER;
			break;

		case kFskTextAlignRight:
			flags |= DT_RIGHT;
			break;
	}

	switch (vAlign) {
		case kFskTextAlignTop:
		default:
			flags |= DT_TOP;
			break;

		case kFskTextAlignCenter:
			flags |= DT_VCENTER;
			break;

		case kFskTextAlignBottom:
			flags |= DT_BOTTOM;
			break;
	}
#endif

	{
	SIZE sz;
	UINT align;
	SInt32 y;
	char *encodedText = (char *)scratchBuffer;
	UInt32 encodedTextLen = sizeof(scratchBuffer);
	if (kFskErrNone != FskTextUTF8ToUnicode16NENoAlloc(text, textLen, (UInt16 *)scratchBuffer, &encodedTextLen)) {
		if (kFskErrNone != FskMemPtrNew(encodedTextLen, &encodedText)) {
			FskBitmapDispose(scratchBits);
			goto done;
		}
		FskTextUTF8ToUnicode16NENoAlloc(text, textLen, (UInt16 *)encodedText, &encodedTextLen);
	}

	encodedTextLen >>= 1;
	remapForMicrosoft((UInt16 *)encodedText, encodedTextLen);

	if (kFskTextTruncateCenter & textStyle) {
		// work hard to truncate the center, since Windows doesn't support this directly
		SIZE size;
		int *widths;

		if (kFskErrNone == FskMemPtrNew(sizeof(int) * encodedTextLen, (FskMemPtr *)&widths)) {
			int maxC, i, fitWidth = (r.right - r.left);
			GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, 32768, &maxC, widths, &size);
			if (size.cx > fitWidth) {
				SInt32 currentWidth = size.cx;
				SInt32 truncBegin, truncEnd;
				WCHAR ellipsis = 0x2026;
				SIZE ellipsisSize;
				UInt16 *uniChars = (UInt16 *)encodedText;

				for (i = encodedTextLen - 1; i > 0; i--)
					widths[i] -= widths[i - 1];

				GetTextExtentPoint32W(dc, (LPWSTR)&ellipsis, 1, &ellipsisSize);		//@@ could use ellipsisWidth in cache here
				fitWidth -= ellipsisSize.cx;

				if (fitWidth > 0) {
					Boolean phase = true;		// start towards the end
					truncBegin = truncEnd = encodedTextLen / 2;
					while ((currentWidth > fitWidth) && ((truncEnd - truncBegin) != encodedTextLen)) {
						if (phase) {
							if (truncEnd < (SInt32)encodedTextLen) {
								currentWidth -= widths[truncEnd];
								truncEnd += 1;
							}
						}
						else {
							if (0 != truncBegin) {
								truncBegin -= 1;
								currentWidth -= widths[truncBegin];
							}
						}
						phase = !phase;
					}
					FskMemMove(&uniChars[truncBegin + 1], &uniChars[truncEnd], (encodedTextLen - truncEnd) * 2);
					uniChars[truncBegin] = ellipsis;
					encodedTextLen -= (truncEnd - truncBegin);
					encodedTextLen += 1;

					flags &= ~DT_END_ELLIPSIS;
				}
			}

			FskMemPtrDispose(widths);
		}
	}

#if 0
	DrawTextW(dc, (LPWSTR)encodedText, encodedTextLen, &r, flags);
#else
	if (kFskTextTruncateEnd & textStyle) {
		int fitChars;
		int stackWidths[256], *widths, width = r.right - r.left;
		WCHAR ellipsis = 0x2026;
		SIZE ellipsisSz;

		if (encodedTextLen < 256)
			widths = stackWidths;
		else {
			if (kFskErrNone != FskMemPtrNew(sizeof(int) * encodedTextLen, (FskMemPtr *)&widths)) {
				widths = stackWidths;
				encodedTextLen = 256;
			}
		}

		GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, width, &fitChars, widths, &sz);
		if ((UInt32)fitChars < encodedTextLen) {
			// remove trailing white space
			if (formatCache) {
				if (!formatCache->haveEllipsisWidth) {
					GetTextExtentExPointW(dc, (WCHAR *)&ellipsis, 1, 0, NULL, NULL, &ellipsisSz);
					formatCache->haveEllipsisWidth = true;
					formatCache->ellipsisWidth = ellipsisSz.cx;
				}
				else
					ellipsisSz.cx = formatCache->ellipsisWidth;
			}
			else
				GetTextExtentExPointW(dc, (WCHAR *)&ellipsis, 1, 0, NULL, NULL, &ellipsisSz);

			if (width > ellipsisSz.cx) {
				width -= ellipsisSz.cx;

				while (fitChars > 2) {
					UInt16 c = ((UInt16 *)encodedText)[fitChars - 2];

					if ((32 != c) && (9 != c) && (0x3000 != c))
						break;

					fitChars -= 1;
				}

				// truncate if needed to make room for the ellipsis
				while ((widths[fitChars - 1] > width) && (fitChars > 2))
					fitChars -= 1;

				// add ellipsis
				((UInt16 *)encodedText)[fitChars - 1] = 0x2026;		// ellipsis
				encodedTextLen = fitChars;
			}
			else
				encodedTextLen = 0;
		}

		if (widths != stackWidths)
			FskMemPtrDispose(widths);
	}
	else {
		if (kFskTextAlignCenter == vAlign)
			GetTextExtentExPointW(dc, (WCHAR *)encodedText, encodedTextLen, 0, NULL, NULL, &sz);
	}

	if (kFskTextAlignCenter == vAlign) {
		y = (r.top + r.bottom - sz.cy) >> 1;
		align = TA_TOP;
	}
	else
	if (kFskTextAlignTop == vAlign) {