Example #1
0
static void test_flatten(void)
{
    GpStatus status;
    GpPath *path;
    GpMatrix *m;

    status = GdipCreatePath(FillModeAlternate, &path);
    expect(Ok, status);
    status = GdipCreateMatrix(&m);
    expect(Ok, status);

    /* NULL arguments */
    status = GdipFlattenPath(NULL, NULL, 0.0);
    expect(InvalidParameter, status);
    status = GdipFlattenPath(NULL, m, 0.0);
    expect(InvalidParameter, status);

    /* flatten empty path */
    status = GdipFlattenPath(path, NULL, 1.0);
    expect(Ok, status);

    status = GdipTransformPath(path, 0);
    expect(Ok, status);

    status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 50.0);
    expect(Ok, status);

    status = GdipFlattenPath(path, NULL, 1.0);
    expect(Ok, status);
    ok_path(path, flattenellipse_path, sizeof(flattenellipse_path)/sizeof(path_test_t), TRUE);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 100.0);
    expect(Ok, status);
    status = GdipFlattenPath(path, NULL, 1.0);
    expect(Ok, status);
    ok_path(path, flattenline_path, sizeof(flattenline_path)/sizeof(path_test_t), FALSE);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 50.0, 0.0, 90.0);
    expect(Ok, status);
    status = GdipFlattenPath(path, NULL, 1.0);
    expect(Ok, status);
    ok_path(path, flattenarc_path, sizeof(flattenarc_path)/sizeof(path_test_t), TRUE);

    /* easy case - quater of a full circle */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
    expect(Ok, status);
    status = GdipFlattenPath(path, NULL, 1.0);
    expect(Ok, status);
    ok_path(path, flattenquater_path, sizeof(flattenquater_path)/sizeof(path_test_t), FALSE);

    GdipDeleteMatrix(m);
    GdipDeletePath(path);
}
Example #2
0
static
GF_Err gdip_attach_surface_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat)
{
	GpMatrix *mat;
	u32 pFormat;
	GPGRAPH();

	if (pitch_y%4) return GF_NOT_SUPPORTED;

	switch (pixelFormat) {
	case GF_PIXEL_ALPHAGREY:
		pFormat = PixelFormat16bppGrayScale;
		if (pitch_x != 2) return GF_NOT_SUPPORTED;
		break;
	case GF_PIXEL_RGB_555:
		pFormat = PixelFormat16bppRGB555;
		if (pitch_x != 2) return GF_NOT_SUPPORTED;
		break;
	case GF_PIXEL_RGB_565:
		pFormat = PixelFormat16bppRGB565;
		if (pitch_x != 2) return GF_NOT_SUPPORTED;
		break;
	case GF_PIXEL_RGB_24:
		pFormat = PixelFormat24bppRGB;
		if (pitch_x != 3) return GF_NOT_SUPPORTED;
		break;
	case GF_PIXEL_RGB_32:
		pFormat = PixelFormat32bppRGB;
		if (pitch_x != 4) return GF_NOT_SUPPORTED;
		break;
	case GF_PIXEL_ARGB:
		pFormat = PixelFormat32bppARGB;
		if (pitch_x != 4) return GF_NOT_SUPPORTED;
		break;
	default:
		return GF_NOT_SUPPORTED;
	}
	GdipCreateBitmapFromScan0(width, height, pitch_y, pFormat, (unsigned char*)pixels, &_graph->pBitmap);
	GdipGetImageGraphicsContext(_graph->pBitmap, &_graph->graph);

	_graph->w = width;
	_graph->h = height;
	if (_graph->center_coords) {
		GdipCreateMatrix(&mat);
		GdipScaleMatrix(mat, 1.0, -1.0, MatrixOrderAppend);
		GdipTranslateMatrix(mat, (Float) width/2, (Float) height/2, MatrixOrderAppend);
		GdipSetWorldTransform(_graph->graph, mat);
		GdipDeleteMatrix(mat);
	}
	GdipSetPixelOffsetMode(_graph->graph, GDIP_PIXEL_MODE);
	return GF_OK;
}
Example #3
0
static 
GF_Err gdip_set_linear_gradient (GF_STENCIL _this, Fixed start_x, Fixed start_y, Fixed end_x, Fixed end_y)
{
	GPSTEN();
	CHECK_RET(GF_STENCIL_LINEAR_GRADIENT);
	if (_sten->pLinear) GdipDeleteBrush(_sten->pLinear);

	_sten->start.X = FIX2FLT(start_x);
	_sten->start.Y = FIX2FLT(start_y);
	_sten->end.X = FIX2FLT(end_x);
	_sten->end.Y = FIX2FLT(end_y);

	GdipCreateLineBrush(&_sten->start, &_sten->end, 0xFF000000, 0xFFFFFFFF, WrapModeTile, &_sten->pLinear);
	if (!_sten->pLinearMat) GdipCreateMatrix(&_sten->pLinearMat);
	GdipGetLineTransform(_sten->pLinear, _sten->pLinearMat);
	_sten->needs_rebuild = GF_TRUE;
	return GF_OK;
}
Example #4
0
static
GF_Err gdip_attach_surface_to_texture(GF_SURFACE _this, GF_STENCIL sten)
{
	GpMatrix *mat;
	struct _stencil *_sten = (struct _stencil *)sten;
	GPGRAPH();
	if (!_graph || !_sten || !_sten->pBitmap) return GF_BAD_PARAM;

	GdipGetImageGraphicsContext(_sten->pBitmap, &_graph->graph);

	if (_graph->center_coords) {
		GdipCreateMatrix(&mat);
		GdipScaleMatrix(mat, 1.0, -1.0, MatrixOrderAppend);
		GdipTranslateMatrix(mat, (Float) _sten->width/2, (Float) _sten->height/2, MatrixOrderAppend);
		GdipSetWorldTransform(_graph->graph, mat);
		GdipDeleteMatrix(mat);
	}
	_graph->w = _sten->width;
	_graph->h = _sten->height;
	GdipSetPixelOffsetMode(_graph->graph, GDIP_PIXEL_MODE);
	return GF_OK;
}
Example #5
0
static
GF_Err gdip_attach_surface_to_device(GF_SURFACE _this, void *os_handle, u32 width, u32 height)
{
	GpMatrix *mat;
	HDC handle = (HDC) os_handle;
	GPGRAPH();
	if (!_graph || !handle) return GF_BAD_PARAM;
	if (_graph->graph) return GF_BAD_PARAM;
	GdipCreateFromHDC(handle, &_graph->graph);

	GdipCreateMatrix(&mat);
	if (	_graph->center_coords) {
		GdipScaleMatrix(mat, 1.0, -1.0, MatrixOrderAppend);
		GdipTranslateMatrix(mat, (Float) width/2, (Float) height/2, MatrixOrderAppend);
	}
	GdipSetWorldTransform(_graph->graph, mat);
	GdipDeleteMatrix(mat);
	_graph->w = width;
	_graph->h = height;
	GdipSetPixelOffsetMode(_graph->graph, GDIP_PIXEL_MODE);
	return GF_OK;
}
Example #6
0
/*GDIplus is completely bugged here, we MUST build the gradient in local coord system and apply translation
after, otherwise performances are just horrible*/
void gdip_recompute_radial_gradient(GF_STENCIL _this)
{
	s32 repeat, k;
	u32 i;
	GpPointF pt;
	GpMatrix *mat;
	GPSTEN();


	if (!_sten->needs_rebuild) return;
	_sten->needs_rebuild = GF_FALSE;


	if (_sten->pRadial) {
		GdipDeleteBrush(_sten->pRadial);
		_sten->pRadial = NULL;
	}
	if (_sten->pSolid) {
		GdipDeleteBrush(_sten->pSolid);
		_sten->pSolid = NULL;
	}
	if (_sten->circle) {
		GdipDeletePath(_sten->circle);
		_sten->circle = NULL;
	}

	GdipCreatePath(FillModeAlternate, &_sten->circle);
	/*get number of repeats*/
	if (_sten->spread == GF_GRADIENT_MODE_PAD) {


		GdipAddPathEllipse(_sten->circle, - _sten->radius.X, -_sten->radius.Y, 
								2*_sten->radius.X, 2*_sten->radius.Y);
	
		GdipCreatePathGradientFromPath(_sten->circle, &_sten->pRadial);

		ARGB *blends = new ARGB[_sten->num_pos + 1];

		/*radial blend pos are from bounds to center in gdiplus*/
		blends[0] = _sten->cols[_sten->num_pos - 1];
		for (i=0; i<_sten->num_pos;i++) {
			blends[i+1] = _sten->cols[_sten->num_pos - i - 1];
		}
	
		REAL *pos = new REAL[_sten->num_pos + 1];
		pos[0] = 0;
		for (i=0; i<_sten->num_pos;i++) {
			pos[i+1] = _sten->pos[i];
		}

		GdipSetPathGradientPresetBlend(_sten->pRadial, blends, pos, _sten->num_pos + 1);
		delete [] blends;
		delete [] pos;

		/*set focal*/
		pt = _sten->focal;
		pt.X -= _sten->center.X;
		pt.Y -= _sten->center.Y;
		GdipSetPathGradientCenterPoint(_sten->pRadial, &pt);	

		/*set transform*/
		GdipCreateMatrix(&mat);
		GdipTranslateMatrix(mat, _sten->center.X, _sten->center.Y, MatrixOrderAppend);
		if (_sten->pMat) GdipMultiplyMatrix(mat, _sten->pMat, MatrixOrderAppend);
		GdipSetTextureTransform((GpTexture*)_sten->pRadial, mat);
		GdipDeleteMatrix(mat);

		/*create back brush*/
		GdipCreateSolidFill(_sten->cols[_sten->num_pos - 1], &_sten->pSolid);
		GdipResetPath(_sten->circle);
		GdipAddPathEllipse(_sten->circle, - _sten->radius.X + _sten->center.X, -_sten->radius.Y + _sten->center.Y, 
								2*_sten->radius.X, 2*_sten->radius.Y);

	} else {
		repeat = 10;

		GdipAddPathEllipse(_sten->circle, - repeat * _sten->radius.X, - repeat*_sten->radius.Y, 
								2*repeat*_sten->radius.X,  2*repeat*_sten->radius.Y);

		GdipCreatePathGradientFromPath(_sten->circle, &_sten->pRadial);
		GdipDeletePath(_sten->circle);
		_sten->circle = NULL;

		ARGB *blends = new ARGB[_sten->num_pos*repeat];
		REAL *pos = new REAL[_sten->num_pos*repeat];

		if (_sten->spread == GF_GRADIENT_MODE_REPEAT) {
			for (k=0; k<repeat; k++) {
				for (i=0; i<_sten->num_pos; i++) {
					blends[k*_sten->num_pos + i] = _sten->cols[_sten->num_pos - i - 1];
					pos[k*_sten->num_pos + i] = (k + _sten->pos[i]) / repeat;
				}
			}
		} else {
			for (k=0; k<repeat; k++) {
				for (i=0; i<_sten->num_pos; i++) {
					u32 index = (k%2) ? (_sten->num_pos-i-1) : i;
					blends[k*_sten->num_pos + i] = _sten->cols[index];
					if (k%2) {
						pos[k*_sten->num_pos + i] = (k + (1 - _sten->pos[index]) ) / repeat;
					} else {
						pos[k*_sten->num_pos + i] = ( k + _sten->pos[i] ) / repeat;
					}
				}
			}
		}
		GdipSetPathGradientPresetBlend(_sten->pRadial, blends, pos, _sten->num_pos*repeat);
		delete [] pos;
		delete [] blends;


		/*set focal*/
		pt = _sten->focal;
		pt.X -= (1 - repeat) * (_sten->focal.X - _sten->center.X) + _sten->center.X;
		pt.Y -= (1 - repeat) * (_sten->focal.Y - _sten->center.Y) + _sten->center.Y;
		GdipSetPathGradientCenterPoint(_sten->pRadial, &pt);	

		/*set transform*/
		GdipCreateMatrix(&mat);
		GdipTranslateMatrix(mat, (1 - repeat) * (_sten->focal.X - _sten->center.X) + _sten->center.X,
								(1 - repeat) * (_sten->focal.Y - _sten->center.Y) + _sten->center.Y, 
								MatrixOrderAppend);
		if (_sten->pMat) GdipMultiplyMatrix(mat, _sten->pMat, MatrixOrderAppend);
		GdipSetTextureTransform((GpTexture*)_sten->pRadial, mat);
		GdipDeleteMatrix(mat);

		GdipSetPathGradientWrapMode(_sten->pRadial, WrapModeTileFlipXY);
	}
}
Example #7
0
static void test_transform(void)
{
    GpStatus status;
    GpPen *pen;
    GpMatrix *matrix, *matrix2;
    REAL values[6];

    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
    expect(Ok, status);

    status = GdipCreateMatrix(&matrix);
    expect(Ok, status);

    status = GdipGetPenTransform(pen, matrix);
    todo_wine expect(Ok, status);

    status = GdipGetMatrixElements(matrix, values);
    expect(Ok, status);

    expectf(1.0, values[0]);
    expectf(0.0, values[1]);
    expectf(0.0, values[2]);
    expectf(1.0, values[3]);
    expectf(0.0, values[4]);
    expectf(0.0, values[5]);

    GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix2);
    status = GdipSetPenTransform(pen, matrix2);
    todo_wine expect(Ok, status);
    GdipDeleteMatrix(matrix2);

    status = GdipGetPenTransform(pen, matrix);
    todo_wine expect(Ok, status);
    status = GdipGetMatrixElements(matrix, values);
    expect(Ok, status);
todo_wine {
    expectf(3.0,  values[0]);
    expectf(-2.0,  values[1]);
    expectf(5.0,  values[2]);
    expectf(2.0, values[3]);
    expectf(6.0, values[4]);
    expectf(3.0,  values[5]);
}
    status = GdipResetPenTransform(pen);
    todo_wine expect(Ok, status);

    status = GdipGetPenTransform(pen, matrix);
    todo_wine expect(Ok, status);
    status = GdipGetMatrixElements(matrix, values);
    expect(Ok, status);

    expectf(1.0, values[0]);
    expectf(0.0, values[1]);
    expectf(0.0, values[2]);
    expectf(1.0, values[3]);
    expectf(0.0, values[4]);
    expectf(0.0, values[5]);

    GdipDeletePen(pen);

    GdipDeleteMatrix(matrix);
}
Example #8
0
File: font.c Project: Dietr1ch/wine
static void test_font_transform(void)
{
    static const WCHAR string[] = { 'A',0 };
    GpStatus status;
    HDC hdc;
    LOGFONTA lf;
    GpFont *font;
    GpGraphics *graphics;
    GpMatrix *matrix;
    GpStringFormat *format, *typographic;
    PointF pos[1] = { { 0,0 } };
    REAL height, margin_y;
    RectF bounds, rect;

    hdc = CreateCompatibleDC(0);
    status = GdipCreateFromHDC(hdc, &graphics);
    expect(Ok, status);

    status = GdipSetPageUnit(graphics, UnitPixel);
    expect(Ok, status);

    status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
    expect(Ok, status);
    status = GdipStringFormatGetGenericTypographic(&typographic);
    expect(Ok, status);

    memset(&lf, 0, sizeof(lf));
    lstrcpyA(lf.lfFaceName, "Tahoma");
    lf.lfHeight = -100;
    lf.lfWidth = 100;
    status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
    expect(Ok, status);

    margin_y = 100.0 / 8.0;

    /* identity matrix */
    status = GdipCreateMatrix(&matrix);
    expect(Ok, status);
    status = GdipSetWorldTransform(graphics, matrix);
    expect(Ok, status);
    status = GdipGetLogFontA(font, graphics, &lf);
    expect(Ok, status);
    expect(-100, lf.lfHeight);
    expect(0, lf.lfWidth);
    expect(0, lf.lfEscapement);
    expect(0, lf.lfOrientation);
    status = GdipGetFontHeight(font, graphics, &height);
    expect(Ok, status);
    expectf(120.703125, height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
todo_wine
    expectf(height + margin_y, bounds.Height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
    expectf_(height, bounds.Height, 1.0);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, NULL, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.05);
    expectf_(height, bounds.Height, 0.5);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, matrix, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.05);
    expectf_(height, bounds.Height, 0.5);

    /* scale matrix */
    status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend);
    expect(Ok, status);
    status = GdipSetWorldTransform(graphics, matrix);
    expect(Ok, status);
    status = GdipGetLogFontA(font, graphics, &lf);
    expect(Ok, status);
    expect(-300, lf.lfHeight);
    expect(0, lf.lfWidth);
    expect(0, lf.lfEscapement);
    expect(0, lf.lfOrientation);
    status = GdipGetFontHeight(font, graphics, &height);
    expect(Ok, status);
    expectf(120.703125, height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
todo_wine
    expectf(height + margin_y, bounds.Height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
    expectf_(height, bounds.Height, 0.05);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, NULL, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.05);
    expectf_(height, bounds.Height, 0.2);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, matrix, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
todo_wine
    expectf_(-300.0, bounds.Y, 0.15);
todo_wine
    expectf(height * 3.0, bounds.Height);

    /* scale + ratate matrix */
    status = GdipRotateMatrix(matrix, 45.0, MatrixOrderAppend);
    expect(Ok, status);
    status = GdipSetWorldTransform(graphics, matrix);
    expect(Ok, status);
    status = GdipGetLogFontA(font, graphics, &lf);
    expect(Ok, status);
    expect(-300, lf.lfHeight);
    expect(0, lf.lfWidth);
    expect_(3151, lf.lfEscapement, 1);
    expect_(3151, lf.lfOrientation, 1);
    status = GdipGetFontHeight(font, graphics, &height);
    expect(Ok, status);
    expectf(120.703125, height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
todo_wine
    expectf(height + margin_y, bounds.Height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
    expectf_(height, bounds.Height, 0.05);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, NULL, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.05);
    expectf_(height, bounds.Height, 0.2);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, matrix, &bounds);
    expect(Ok, status);
todo_wine
    expectf_(-43.814377, bounds.X, 0.05);
todo_wine
    expectf_(-212.235611, bounds.Y, 0.05);
todo_wine
    expectf_(340.847534, bounds.Height, 0.05);

    /* scale + ratate + shear matrix */
    status = GdipShearMatrix(matrix, 4.0, 5.0, MatrixOrderAppend);
    expect(Ok, status);
    status = GdipSetWorldTransform(graphics, matrix);
    expect(Ok, status);
    status = GdipGetLogFontA(font, graphics, &lf);
    expect(Ok, status);
todo_wine
    expect(1032, lf.lfHeight);
    expect(0, lf.lfWidth);
    expect_(3099, lf.lfEscapement, 1);
    expect_(3099, lf.lfOrientation, 1);
    status = GdipGetFontHeight(font, graphics, &height);
    expect(Ok, status);
    expectf(120.703125, height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
todo_wine
    expectf(height + margin_y, bounds.Height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
    expectf_(height, bounds.Height, 0.2);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, NULL, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.2);
    expectf_(height, bounds.Height, 0.2);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, matrix, &bounds);
    expect(Ok, status);
todo_wine
    expectf_(-636.706848, bounds.X, 0.05);
todo_wine
    expectf_(-175.257523, bounds.Y, 0.05);
todo_wine
    expectf_(1532.984985, bounds.Height, 0.05);

    /* scale + ratate + shear + translate matrix */
    status = GdipTranslateMatrix(matrix, 10.0, 20.0, MatrixOrderAppend);
    expect(Ok, status);
    status = GdipSetWorldTransform(graphics, matrix);
    expect(Ok, status);
    status = GdipGetLogFontA(font, graphics, &lf);
    expect(Ok, status);
todo_wine
    expect(1032, lf.lfHeight);
    expect(0, lf.lfWidth);
    expect_(3099, lf.lfEscapement, 1);
    expect_(3099, lf.lfOrientation, 1);
    status = GdipGetFontHeight(font, graphics, &height);
    expect(Ok, status);
    expectf(120.703125, height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
todo_wine
    expectf(height + margin_y, bounds.Height);
    set_rect_empty(&rect);
    set_rect_empty(&bounds);
    status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf(0.0, bounds.Y);
    expectf_(height, bounds.Height, 0.1);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, NULL, &bounds);
    expect(Ok, status);
    expectf(0.0, bounds.X);
    expectf_(-100.0, bounds.Y, 0.2);
    expectf_(height, bounds.Height, 0.2);
    set_rect_empty(&bounds);
    status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
                                     DriverStringOptionsCmapLookup, matrix, &bounds);
    expect(Ok, status);
todo_wine
    expectf_(-626.706848, bounds.X, 0.05);
todo_wine
    expectf_(-155.257523, bounds.Y, 0.05);
todo_wine
    expectf_(1532.984985, bounds.Height, 0.05);

    GdipDeleteMatrix(matrix);
    GdipDeleteFont(font);
    GdipDeleteGraphics(graphics);
    GdipDeleteStringFormat(typographic);
    GdipDeleteStringFormat(format);
    DeleteDC(hdc);
}
Example #9
0
static void test_widen(void)
{
    GpStatus status;
    GpPath *path;
    GpPen *pen;
    GpMatrix *m;
    INT count=-1;

    status = GdipCreatePath(FillModeAlternate, &path);
    expect(Ok, status);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitPixel, &pen);
    expect(Ok, status);
    status = GdipCreateMatrix(&m);
    expect(Ok, status);

    /* NULL arguments */
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);
    status = GdipWidenPath(NULL, NULL, NULL, 0.0);
    expect(InvalidParameter, status);
    status = GdipWidenPath(path, pen, m, 0.0);
    expect(Ok, status);
    status = GdipWidenPath(path, pen, NULL, 1.0);
    expect(Ok, status);
    status = GdipWidenPath(path, NULL, m, 1.0);
    expect(InvalidParameter, status);
    status = GdipWidenPath(NULL, pen, m, 1.0);
    expect(InvalidParameter, status);

    /* widen empty path */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipWidenPath(path, pen, m, 1.0);
    expect(OutOfMemory, status);

    /* horizontal line */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* horizontal 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* vertical 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
    expect(Ok, status);

    /* dashed line */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
    expect(Ok, status);

    status = GdipSetPenDashStyle(pen, DashStyleDash);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_dash_path, sizeof(widenline_dash_path)/sizeof(path_test_t), FALSE);

    status = GdipSetPenDashStyle(pen, DashStyleSolid);
    expect(Ok, status);

    /* pen width in UnitWorld */
    GdipDeletePen(pen);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
    expect(Ok, status);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* horizontal 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* vertical 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_wide_path, sizeof(widenline_wide_path)/sizeof(path_test_t), FALSE);

    status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
    expect(Ok, status);

    /* pen width in UnitInch */
    GdipDeletePen(pen);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
    expect(Ok, status);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* pen width = 0 pixels - native fails to widen but can draw with this pen */
    GdipDeletePen(pen);
    status = GdipCreatePen1(0xffffffff, 0.0, UnitPixel, &pen);
    expect(Ok, status);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);

    status = GdipGetPointCount(path, &count);
    expect(Ok, status);
    todo_wine expect(0, count);

    GdipDeleteMatrix(m);
    GdipDeletePen(pen);
    GdipDeletePath(path);
}
Example #10
0
static void test_widen(void)
{
    GpStatus status;
    GpPath *path;
    GpPen *pen;
    GpMatrix *m;

    status = GdipCreatePath(FillModeAlternate, &path);
    expect(Ok, status);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitPixel, &pen);
    expect(Ok, status);
    status = GdipCreateMatrix(&m);
    expect(Ok, status);

    /* NULL arguments */
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);
    status = GdipWidenPath(NULL, NULL, NULL, 0.0);
    expect(InvalidParameter, status);
    status = GdipWidenPath(path, pen, m, 0.0);
    expect(Ok, status);
    status = GdipWidenPath(path, pen, NULL, 1.0);
    expect(Ok, status);
    status = GdipWidenPath(path, NULL, m, 1.0);
    expect(InvalidParameter, status);
    status = GdipWidenPath(NULL, pen, m, 1.0);
    expect(InvalidParameter, status);

    /* widen empty path */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipWidenPath(path, pen, m, 1.0);
    expect(OutOfMemory, status);

    /* horizontal line */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* horizontal 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* vertical 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
    expect(Ok, status);

    /* pen width in UnitWorld */
    GdipDeletePen(pen);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
    expect(Ok, status);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* horizontal 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    /* vertical 2x stretch */
    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
    expect(Ok, status);

    status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_wide_path, sizeof(widenline_wide_path)/sizeof(path_test_t), FALSE);

    status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
    expect(Ok, status);

    /* pen width in UnitInch */
    GdipDeletePen(pen);
    status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
    expect(Ok, status);

    status = GdipResetPath(path);
    expect(Ok, status);
    status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
    expect(Ok, status);

    status = GdipWidenPath(path, pen, m, 1.0);
    expect(Ok, status);
    ok_path(path, widenline_path, sizeof(widenline_path)/sizeof(path_test_t), FALSE);

    GdipDeleteMatrix(m);
    GdipDeletePen(pen);
    GdipDeletePath(path);
}
Example #11
0
static GF_Glyph *gdip_load_glyph(GF_FontReader *dr, u32 glyph_name)
{
	GF_Rect bounds;
	GF_Glyph *glyph;
	GpPath *path_tmp;
	GpStringFormat *fmt;
	GpMatrix *mat;
	Float est_advance_h;
	unsigned short str[4];
	int i;
	FontPriv *ctx = (FontPriv *)dr->udta;

	if (!ctx->font) return NULL;

	RectF rc;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;

	GdipCreateStringFormat(StringFormatFlagsNoWrap | StringFormatFlagsNoFitBlackBox | StringFormatFlagsMeasureTrailingSpaces, LANG_NEUTRAL, &fmt);
	GdipSetStringFormatAlign(fmt, StringAlignmentNear);
	GdipCreatePath(FillModeAlternate, &path_tmp);

	if (glyph_name==0x20) {
		est_advance_h = ctx->whitespace_width;
	} else {
		/*to compute first glyph alignment (say 'x', we figure out its bounding full box by using the '_' char as wrapper (eg, "_x_")
		then the bounding box starting from xMin of the glyph ('x_'). The difference between both will give us a good approx 
		of the glyph alignment*/
		str[0] = glyph_name;
		str[1] = (unsigned short) '_';
		str[2] = (unsigned short) 0;
		GdipAddPathString(path_tmp, (const WCHAR *)str, -1, ctx->font, ctx->font_style, ctx->em_size, &rc, fmt);
		GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);
		est_advance_h = rc.Width - ctx->underscore_width;
	}
	
	GdipResetPath(path_tmp);

	str[0] = glyph_name;
	str[1] = (unsigned short) 0;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;
	GdipAddPathString(path_tmp, (const WCHAR *)str, -1, ctx->font, ctx->font_style, ctx->em_size, &rc, fmt);

	GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);

	/*flip so that we are in a font coordinate system - also move back the glyph to x=0 and y=baseline, GdiPlus doesn't do so*/
	GdipCreateMatrix(&mat);
	GdipTranslateMatrix(mat, - rc.X, -ctx->ascent, MatrixOrderAppend);
	GdipScaleMatrix(mat, 1, -1, MatrixOrderAppend);
	GdipTransformPath(path_tmp, mat);
	GdipDeleteMatrix(mat);


	/*start enum*/
	s32 count;
	GdipGetPointCount(path_tmp, &count);
	GpPointF *pts = new GpPointF[count];
	BYTE *types = new BYTE[count];
	GdipGetPathTypes(path_tmp, types, count);
	GdipGetPathPoints(path_tmp, pts, count);

	GF_SAFEALLOC(glyph, GF_Glyph);
	GF_SAFEALLOC(glyph->path, GF_Path);

	for (i=0; i<count; ) {
		BOOL closed = 0;
		s32 sub_type;
		
		sub_type = types[i] & PathPointTypePathTypeMask;

		if (sub_type == PathPointTypeStart) {
			gf_path_add_move_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y));
			i++;
		}
		else if (sub_type == PathPointTypeLine) {
			gf_path_add_line_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y));
		
			if (types[i] & PathPointTypeCloseSubpath) gf_path_close(glyph->path);

			i++;
		}
		else if (sub_type == PathPointTypeBezier) {
			assert(i+2<=count);
			gf_path_add_cubic_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y), FLT2FIX(pts[i+1].X), FLT2FIX(pts[i+1].Y), FLT2FIX(pts[i+2].X), FLT2FIX(pts[i+2].Y));

			if (types[i+2] & PathPointTypeCloseSubpath) gf_path_close(glyph->path);

			i += 3;
		} else {
			assert(0);
			break;
		}
	}
	
	delete [] pts;
	delete [] types;
	GdipDeleteStringFormat(fmt);
	GdipDeletePath(path_tmp);

	glyph->ID = glyph_name;
	glyph->utf_name = glyph_name;
	glyph->vert_advance = (s32) (ctx->ascent-ctx->descent);
	glyph->horiz_advance = (s32) est_advance_h;
	gf_path_get_bounds(glyph->path, &bounds);
	glyph->width = FIX2INT(bounds.width);
	glyph->height = FIX2INT(bounds.height);
	return glyph;
}
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
    GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *destPoints, INT count,
    GDIPCONST GpRectF *srcRect, Unit srcUnit, EnumerateMetafileProc callback,
    VOID *callbackData, GDIPCONST GpImageAttributes *imageAttributes)
{
    struct enum_metafile_data data;
    GpStatus stat;
    GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this const was joking */
    GraphicsContainer state;
    GpPath *dst_path;

    TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
        destPoints, count, srcRect, srcUnit, callback, callbackData,
        imageAttributes);

    if (!graphics || !metafile || !destPoints || count != 3 || !srcRect)
        return InvalidParameter;

    if (!metafile->hemf)
        return InvalidParameter;

    if (metafile->playback_graphics)
        return ObjectBusy;

    TRACE("%s %i -> %s %s %s\n", debugstr_rectf(srcRect), srcUnit,
        debugstr_pointf(&destPoints[0]), debugstr_pointf(&destPoints[1]),
        debugstr_pointf(&destPoints[2]));

    data.callback = callback;
    data.callback_data = callbackData;
    data.metafile = real_metafile;

    real_metafile->playback_graphics = graphics;
    real_metafile->playback_dc = NULL;
    real_metafile->src_rect = *srcRect;

    memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3);
    stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3);

    if (stat == Ok)
        stat = GdipBeginContainer2(graphics, &state);

    if (stat == Ok)
    {
        stat = GdipSetPageScale(graphics, 1.0);

        if (stat == Ok)
            stat = GdipSetPageUnit(graphics, UnitPixel);

        if (stat == Ok)
            stat = GdipResetWorldTransform(graphics);

        if (stat == Ok)
            stat = GdipCreateRegion(&real_metafile->base_clip);

        if (stat == Ok)
            stat = GdipGetClip(graphics, real_metafile->base_clip);

        if (stat == Ok)
            stat = GdipCreatePath(FillModeAlternate, &dst_path);

        if (stat == Ok)
        {
            GpPointF clip_points[4];

            clip_points[0] = real_metafile->playback_points[0];
            clip_points[1] = real_metafile->playback_points[1];
            clip_points[2].X = real_metafile->playback_points[1].X + real_metafile->playback_points[2].X
                - real_metafile->playback_points[0].X;
            clip_points[2].Y = real_metafile->playback_points[1].Y + real_metafile->playback_points[2].Y
                - real_metafile->playback_points[0].Y;
            clip_points[3] = real_metafile->playback_points[2];

            stat = GdipAddPathPolygon(dst_path, clip_points, 4);

            if (stat == Ok)
                stat = GdipCombineRegionPath(real_metafile->base_clip, dst_path, CombineModeIntersect);

            GdipDeletePath(dst_path);
        }

        if (stat == Ok)
            stat = GdipCreateMatrix(&real_metafile->world_transform);

        if (stat == Ok)
        {
            real_metafile->page_unit = UnitDisplay;
            real_metafile->page_scale = 1.0;
            stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile);
        }

        if (stat == Ok)
        {
            stat = METAFILE_PlaybackUpdateClip(real_metafile);
        }

        if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf ||
            metafile->metafile_type == MetafileTypeWmfPlaceable ||
            metafile->metafile_type == MetafileTypeWmf))
            stat = METAFILE_PlaybackGetDC(real_metafile);

        if (stat == Ok)
            EnumEnhMetaFile(0, metafile->hemf, enum_metafile_proc, &data, NULL);

        METAFILE_PlaybackReleaseDC(real_metafile);

        GdipDeleteMatrix(real_metafile->world_transform);
        real_metafile->world_transform = NULL;

        GdipDeleteRegion(real_metafile->base_clip);
        real_metafile->base_clip = NULL;

        GdipEndContainer(graphics, state);
    }

    real_metafile->playback_graphics = NULL;

    return stat;
}
Example #13
0
static M4Err gdip_add_text_to_path(FontRaster *dr, LPM4PATH path, Bool flipText,
					const unsigned short* string, Float left, Float top, Float x_scaling, Float y_scaling, 
					Float ascent, M4Rect *bounds)
{
	GpPath *path_tmp;
	GpMatrix *mat;
	GpStringFormat *fmt;
	Float real_start;
	unsigned short str[4];
	FontPriv *ctx = (FontPriv *)dr->priv;

	if (!ctx->font) return M4BadParam;

	
	RectF rc;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;

	/*find first non-space char and estimate its glyph pos since GDIplus doesn't give this info*/
	s32 len = utf8_wcslen(string);
	s32 i=0;
	for (; i<len; i++) {
		if (string[i] != (unsigned short) ' ') break;
	}
	if (i>=len) return M4OK;

	GdipCreateStringFormat(StringFormatFlagsNoWrap | StringFormatFlagsNoFitBlackBox | StringFormatFlagsMeasureTrailingSpaces, LANG_NEUTRAL, &fmt);
	GdipSetStringFormatAlign(fmt, StringAlignmentNear);
	GdipCreatePath(FillModeAlternate, &path_tmp);

	/*to compute first glyph alignment (say 'x', we figure out its bounding full box by using the '_' char as wrapper (eg, "_x_")
	then the bounding box starting from xMin of the glyph ('x_'). The difference between both will give us a good approx 
	of the glyph alignment*/
	str[0] = (unsigned short) '_';
	str[1] = string[i];
	str[2] = (unsigned short) '_';
	str[3] = (unsigned short) 0;
	GdipAddPathString(path_tmp, str, -1, ctx->font, ctx->font_style, ctx->font_size, &rc, fmt);
	GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);
	Float w1 = rc.Width - 2 * ctx->underscore_width;
	
	GdipResetPath(path_tmp);

	str[0] = string[i];
	str[1] = (unsigned short) '_';
	str[2] = (unsigned short) 0;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;
	GdipAddPathString(path_tmp, str, -1, ctx->font, ctx->font_style, ctx->font_size, &rc, fmt);
	GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);
	real_start = w1 - (rc.Width - ctx->underscore_width);

	GdipResetPath(path_tmp);

	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;
	GdipAddPathString(path_tmp, string, -1, ctx->font, ctx->font_style, ctx->font_size, &rc, fmt);
	GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);


	GdipCreateMatrix(&mat);
	Float off_left = rc.X;
	Float off_left_real = rc.X;

	/*adjust all white space at begin*/
	adjust_white_space(string, &off_left, -1*ctx->whitespace_width);

	if (flipText) {
		/*first translate in local system*/
		GdipTranslateMatrix(mat, left - off_left + real_start, -top, MatrixOrderAppend);
		/*then scale as specified*/
		GdipScaleMatrix(mat, x_scaling, -y_scaling, MatrixOrderAppend);
	} else {
		/*first translate in local system*/
		GdipTranslateMatrix(mat, left - off_left + real_start, top-ascent, MatrixOrderAppend);
		/*then scale as specified*/
		GdipScaleMatrix(mat, x_scaling, y_scaling, MatrixOrderAppend);
	}
	GdipTransformPath(path_tmp, mat);

	/*start enum*/
	s32 count;
	GdipGetPointCount(path_tmp, &count);
	GpPointF *pts = new GpPointF[count];
	BYTE *types = new BYTE[count];
	GdipGetPathTypes(path_tmp, types, count);
	GdipGetPathPoints(path_tmp, pts, count);

	for (i=0; i<count; ) {
		BOOL closed = 0;
		s32 sub_type;
		
		sub_type = types[i] & PathPointTypePathTypeMask;

		if (sub_type == PathPointTypeStart) {
			m4_path_add_move_to(path, pts[i].X, pts[i].Y);
			i++;
		}
		else if (sub_type == PathPointTypeLine) {
			m4_path_add_line_to(path, pts[i].X, pts[i].Y);
		
			if (types[i] & PathPointTypeCloseSubpath) m4_path_close(path);

			i++;
		}
		else if (sub_type == PathPointTypeBezier) {
			assert(i+2<=count);
			m4_path_add_cubic_to(path, pts[i].X, pts[i].Y, pts[i+1].X, pts[i+1].Y, pts[i+2].X, pts[i+2].Y);

			if (types[i+2] & PathPointTypeCloseSubpath) m4_path_close(path);

			i += 3;
		} else {
			assert(0);
			break;
		}
	}
	
	delete [] pts;
	delete [] types;
	
	GdipResetPath(path_tmp);
	adjust_white_space(string, &rc.Width, ctx->whitespace_width);
	rc.X = off_left_real;
	rc.X = off_left;
	/*special case where string is just space*/
	if (!rc.Height) rc.Height = 1;

	GdipAddPathRectangles(path_tmp, &rc, 1);
	GdipGetPathWorldBounds(path_tmp, &rc, mat, NULL);
	bounds->x = rc.X;
	bounds->y = rc.Y;
	bounds->width = rc.Width;
	bounds->height = rc.Height;

	GdipDeleteStringFormat(fmt);
	GdipDeletePath(path_tmp);
	GdipDeleteMatrix(mat);
	return M4OK;
}
Example #14
0
static
GF_Err gdip_surface_fill(GF_SURFACE _this, GF_STENCIL stencil)
{
	GpStatus ret;
	GpMatrix *newmat;
	struct _stencil *_sten;
	GPGRAPH();
	if (!_this) return GF_BAD_PARAM;
	if (!_graph->current) return GF_OK;
	_sten = (struct _stencil *)stencil;
	assert(_sten);

#ifdef NODRAW
	return GF_OK;
#endif


	if (_graph->clip) GdipSetClipPath(_graph->graph, _graph->clip, CombineModeReplace);

	switch (_sten->type) {
	case GF_STENCIL_SOLID:
		assert(_sten->pSolid);
		GdipFillPath(_graph->graph, _sten->pSolid, _graph->current);
		break;
	case GF_STENCIL_LINEAR_GRADIENT:
		if (_sten->pMat) {
			/*rebuild gradient*/
			gdip_recompute_line_gradient(_sten);

			GdipResetTextureTransform((GpTexture*)_sten->pLinear);
			if (_sten->pMat) {
				GdipCloneMatrix(_sten->pMat, &newmat);
			} else {
				GdipCreateMatrix(&newmat);
			}
			GdipMultiplyMatrix(newmat, _sten->pLinearMat, MatrixOrderPrepend);
			GdipSetTextureTransform((GpTexture*)_sten->pLinear, newmat);
			GdipDeleteMatrix(newmat);
		}
		GdipFillPath(_graph->graph, _sten->pLinear, _graph->current);
		break;
	case GF_STENCIL_RADIAL_GRADIENT:
		/*build gradient*/
		gdip_recompute_radial_gradient(_sten);

		GdipSetCompositingQuality(_graph->graph, CompositingQualityHighSpeed);
		GdipSetInterpolationMode(_graph->graph, InterpolationModeLowQuality);
		GdipSetSmoothingMode(_graph->graph, SmoothingModeHighSpeed);

		/*check if we need to draw solid background (GDIplus doesn't implement padded mode on path gradients)*/
		if (_sten->pSolid) {
			GpPath *tr;
			GdipClonePath(_sten->circle, &tr);
			GdipTransformPath(tr, _sten->pMat);
			GdipSetClipPath(_graph->graph, tr, CombineModeExclude);
			GdipFillPath(_graph->graph, _sten->pSolid, _graph->current);
			GdipDeletePath(tr);
			GdipResetClip(_graph->graph);
			if (_graph->clip) GdipSetClipPath(_graph->graph, _graph->clip, CombineModeReplace);
		}
		GdipFillPath(_graph->graph, _sten->pRadial, _graph->current);
		break;
	case GF_STENCIL_VERTEX_GRADIENT:
		assert(_sten->pRadial);
		if (_sten->pMat) GdipSetTextureTransform((GpTexture*)_sten->pRadial, _sten->pMat);
		ret = GdipFillPath(_graph->graph, _sten->pRadial, _graph->current);
		break;
	case GF_STENCIL_TEXTURE:
		gdip_load_texture(_sten);
		if (_sten->pTexture) {
			GpMatrix *newmat;
			GdipResetTextureTransform((GpTexture*)_sten->pTexture);
			if (_sten->pMat) {
				GdipCloneMatrix(_sten->pMat, &newmat);
			} else {
				GdipCreateMatrix(&newmat);
			}
			/*gdip flip*/
			if (_graph->center_coords && !(_sten->tiling&GF_TEXTURE_FLIP) )
				GdipScaleMatrix(newmat, 1, -1, MatrixOrderPrepend);
			else if (!_graph->center_coords && (_sten->tiling&GF_TEXTURE_FLIP) )
				GdipScaleMatrix(newmat, 1, -1, MatrixOrderPrepend);

			GdipSetTextureTransform((GpTexture*)_sten->pTexture, newmat);
			GdipDeleteMatrix(newmat);

			GdipSetInterpolationMode(_graph->graph, (_sten->tFilter==GF_TEXTURE_FILTER_HIGH_QUALITY) ? InterpolationModeHighQuality : InterpolationModeLowQuality);
			GdipFillPath(_graph->graph, _sten->pTexture, _graph->current);
		}
		break;
	}
	return GF_OK;
}
Example #15
0
static void test_gradientgetrect(void)
{
    GpLineGradient *brush;
    GpMatrix *transform;
    REAL elements[6];
    GpRectF rectf;
    GpStatus status;
    GpPointF pt1, pt2;

    status = GdipCreateMatrix(&transform);
    expect(Ok, status);

    pt1.X = pt1.Y = 1.0;
    pt2.X = pt2.Y = 100.0;
    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(1.0, rectf.X);
    expectf(1.0, rectf.Y);
    expectf(99.0, rectf.Width);
    expectf(99.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok, status);
        expectf(1.0, elements[0]);
        expectf(1.0, elements[1]);
        expectf(-1.0, elements[2]);
        expectf(1.0, elements[3]);
        expectf(50.50, elements[4]);
        expectf(-50.50, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok, status);
    /* vertical gradient */
    pt1.X = pt1.Y = pt2.X = 0.0;
    pt2.Y = 10.0;
    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(-5.0, rectf.X);
    expectf(0.0, rectf.Y);
    expectf(10.0, rectf.Width);
    expectf(10.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok, status);
        expectf(0.0, elements[0]);
        expectf(1.0, elements[1]);
        expectf(-1.0, elements[2]);
        expectf(0.0, elements[3]);
        expectf(5.0, elements[4]);
        expectf(5.0, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok, status);
    /* horizontal gradient */
    pt1.X = pt1.Y = pt2.Y = 0.0;
    pt2.X = 10.0;
    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(0.0, rectf.X);
    expectf(-5.0, rectf.Y);
    expectf(10.0, rectf.Width);
    expectf(10.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok, status);
        expectf(1.0, elements[0]);
        expectf(0.0, elements[1]);
        expectf(0.0, elements[2]);
        expectf(1.0, elements[3]);
        expectf(0.0, elements[4]);
        expectf(0.0, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok, status);
    /* slope = -1 */
    pt1.X = pt1.Y = 0.0;
    pt2.X = 20.0;
    pt2.Y = -20.0;
    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(0.0, rectf.X);
    expectf(-20.0, rectf.Y);
    expectf(20.0, rectf.Width);
    expectf(20.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok, status);
        expectf(1.0, elements[0]);
        expectf(-1.0, elements[1]);
        expectf(1.0, elements[2]);
        expectf(1.0, elements[3]);
        expectf(10.0, elements[4]);
        expectf(10.0, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok, status);
    /* slope = 1/100 */
    pt1.X = pt1.Y = 0.0;
    pt2.X = 100.0;
    pt2.Y = 1.0;
    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(0.0, rectf.X);
    expectf(0.0, rectf.Y);
    expectf(100.0, rectf.Width);
    expectf(1.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok,status);
        expectf(1.0, elements[0]);
        expectf(0.01, elements[1]);
        expectf(-0.02, elements[2]);
        /* expectf(2.0, elements[3]); */
        expectf(0.01, elements[4]);
        /* expectf(-1.0, elements[5]); */
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok,status);
    /* zero height rect */
    rectf.X = rectf.Y = 10.0;
    rectf.Width = 100.0;
    rectf.Height = 0.0;
    status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeVertical,
        WrapModeTile, &brush);
    expect(OutOfMemory, status);
    /* zero width rect */
    rectf.X = rectf.Y = 10.0;
    rectf.Width = 0.0;
    rectf.Height = 100.0;
    status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal,
        WrapModeTile, &brush);
    expect(OutOfMemory, status);
    /* from rect with LinearGradientModeHorizontal */
    rectf.X = rectf.Y = 10.0;
    rectf.Width = rectf.Height = 100.0;
    status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal,
        WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(10.0, rectf.X);
    expectf(10.0, rectf.Y);
    expectf(100.0, rectf.Width);
    expectf(100.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok,status);
        expectf(1.0, elements[0]);
        expectf(0.0, elements[1]);
        expectf(0.0, elements[2]);
        expectf(1.0, elements[3]);
        expectf(0.0, elements[4]);
        expectf(0.0, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok,status);
    /* passing negative Width/Height to LinearGradientModeHorizontal */
    rectf.X = rectf.Y = 10.0;
    rectf.Width = rectf.Height = -100.0;
    status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal,
        WrapModeTile, &brush);
    expect(Ok, status);
    memset(&rectf, 0, sizeof(GpRectF));
    status = GdipGetLineRect(brush, &rectf);
    expect(Ok, status);
    expectf(10.0, rectf.X);
    expectf(10.0, rectf.Y);
    expectf(-100.0, rectf.Width);
    expectf(-100.0, rectf.Height);
    status = GdipGetLineTransform(brush, transform);
    todo_wine expect(Ok, status);
    if (status == Ok)
    {
        status = GdipGetMatrixElements(transform, elements);
        expect(Ok,status);
        expectf(1.0, elements[0]);
        expectf(0.0, elements[1]);
        expectf(0.0, elements[2]);
        expectf(1.0, elements[3]);
        expectf(0.0, elements[4]);
        expectf(0.0, elements[5]);
    }
    status = GdipDeleteBrush((GpBrush*)brush);
    expect(Ok,status);

    GdipDeleteMatrix(transform);
}