Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbrush.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2007 Google (Evan Stade) 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include <stdarg.h> 00020 00021 #include "windef.h" 00022 #include "winbase.h" 00023 #include "winuser.h" 00024 #include "wingdi.h" 00025 00026 #define COBJMACROS 00027 #include "objbase.h" 00028 #include "olectl.h" 00029 #include "ole2.h" 00030 00031 #include "gdiplus.h" 00032 #include "gdiplus_private.h" 00033 #include "wine/debug.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(gdiplus); 00036 00037 /* 00038 Unix stuff 00039 Code from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/ 00040 */ 00041 double erf(double x) 00042 { 00043 const float a1 = 0.254829592; 00044 const float a2 = -0.284496736; 00045 const float a3 = 1.421413741; 00046 const float a4 = -1.453152027; 00047 const float a5 = 1.061405429; 00048 const float p = 0.3275911; 00049 float t, y, sign; 00050 00051 /* Save the sign of x */ 00052 sign = 1; 00053 if (x < 0) 00054 sign = -1; 00055 x = abs(x); 00056 00057 /* A & S 7.1.26 */ 00058 t = 1.0/(1.0 + p*x); 00059 y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); 00060 00061 return sign*y; 00062 } 00063 00064 /****************************************************************************** 00065 * GdipCloneBrush [GDIPLUS.@] 00066 */ 00067 GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) 00068 { 00069 TRACE("(%p, %p)\n", brush, clone); 00070 00071 if(!brush || !clone) 00072 return InvalidParameter; 00073 00074 switch(brush->bt){ 00075 case BrushTypeSolidColor: 00076 { 00077 *clone = GdipAlloc(sizeof(GpSolidFill)); 00078 if (!*clone) return OutOfMemory; 00079 memcpy(*clone, brush, sizeof(GpSolidFill)); 00080 break; 00081 } 00082 case BrushTypeHatchFill: 00083 { 00084 GpHatch *hatch = (GpHatch*)brush; 00085 00086 return GdipCreateHatchBrush(hatch->hatchstyle, hatch->forecol, hatch->backcol, (GpHatch**)clone); 00087 } 00088 case BrushTypePathGradient:{ 00089 GpPathGradient *src, *dest; 00090 INT count, pcount; 00091 GpStatus stat; 00092 00093 *clone = GdipAlloc(sizeof(GpPathGradient)); 00094 if (!*clone) return OutOfMemory; 00095 00096 src = (GpPathGradient*) brush, 00097 dest = (GpPathGradient*) *clone; 00098 00099 memcpy(dest, src, sizeof(GpPathGradient)); 00100 00101 stat = GdipClonePath(src->path, &dest->path); 00102 00103 if(stat != Ok){ 00104 GdipFree(dest); 00105 return stat; 00106 } 00107 00108 stat = GdipCloneMatrix(src->transform, &dest->transform); 00109 00110 if(stat != Ok){ 00111 GdipDeletePath(dest->path); 00112 GdipFree(dest); 00113 return stat; 00114 } 00115 00116 /* blending */ 00117 count = src->blendcount; 00118 dest->blendcount = count; 00119 dest->blendfac = GdipAlloc(count * sizeof(REAL)); 00120 dest->blendpos = GdipAlloc(count * sizeof(REAL)); 00121 dest->surroundcolors = GdipAlloc(dest->surroundcolorcount * sizeof(ARGB)); 00122 pcount = dest->pblendcount; 00123 if (pcount) 00124 { 00125 dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB)); 00126 dest->pblendpos = GdipAlloc(pcount * sizeof(REAL)); 00127 } 00128 00129 if(!dest->blendfac || !dest->blendpos || !dest->surroundcolors || 00130 (pcount && (!dest->pblendcolor || !dest->pblendpos))){ 00131 GdipDeletePath(dest->path); 00132 GdipDeleteMatrix(dest->transform); 00133 GdipFree(dest->blendfac); 00134 GdipFree(dest->blendpos); 00135 GdipFree(dest->surroundcolors); 00136 GdipFree(dest->pblendcolor); 00137 GdipFree(dest->pblendpos); 00138 GdipFree(dest); 00139 return OutOfMemory; 00140 } 00141 00142 memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); 00143 memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); 00144 memcpy(dest->surroundcolors, src->surroundcolors, dest->surroundcolorcount * sizeof(ARGB)); 00145 00146 if (pcount) 00147 { 00148 memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB)); 00149 memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL)); 00150 } 00151 00152 break; 00153 } 00154 case BrushTypeLinearGradient:{ 00155 GpLineGradient *dest, *src; 00156 INT count, pcount; 00157 00158 dest = GdipAlloc(sizeof(GpLineGradient)); 00159 if(!dest) return OutOfMemory; 00160 00161 src = (GpLineGradient*)brush; 00162 00163 memcpy(dest, src, sizeof(GpLineGradient)); 00164 00165 count = dest->blendcount; 00166 dest->blendfac = GdipAlloc(count * sizeof(REAL)); 00167 dest->blendpos = GdipAlloc(count * sizeof(REAL)); 00168 pcount = dest->pblendcount; 00169 if (pcount) 00170 { 00171 dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB)); 00172 dest->pblendpos = GdipAlloc(pcount * sizeof(REAL)); 00173 } 00174 00175 if (!dest->blendfac || !dest->blendpos || 00176 (pcount && (!dest->pblendcolor || !dest->pblendpos))) 00177 { 00178 GdipFree(dest->blendfac); 00179 GdipFree(dest->blendpos); 00180 GdipFree(dest->pblendcolor); 00181 GdipFree(dest->pblendpos); 00182 GdipFree(dest); 00183 return OutOfMemory; 00184 } 00185 00186 memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); 00187 memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); 00188 00189 if (pcount) 00190 { 00191 memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB)); 00192 memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL)); 00193 } 00194 00195 *clone = &dest->brush; 00196 break; 00197 } 00198 case BrushTypeTextureFill: 00199 { 00200 GpStatus stat; 00201 GpTexture *texture = (GpTexture*)brush; 00202 GpTexture *new_texture; 00203 UINT width, height; 00204 00205 stat = GdipGetImageWidth(texture->image, &width); 00206 if (stat != Ok) return stat; 00207 stat = GdipGetImageHeight(texture->image, &height); 00208 if (stat != Ok) return stat; 00209 00210 stat = GdipCreateTextureIA(texture->image, texture->imageattributes, 0, 0, width, height, &new_texture); 00211 00212 if (stat == Ok) 00213 { 00214 memcpy(new_texture->transform, texture->transform, sizeof(GpMatrix)); 00215 *clone = (GpBrush*)new_texture; 00216 } 00217 else 00218 *clone = NULL; 00219 00220 return stat; 00221 } 00222 default: 00223 ERR("not implemented for brush type %d\n", brush->bt); 00224 return NotImplemented; 00225 } 00226 00227 TRACE("<-- %p\n", *clone); 00228 return Ok; 00229 } 00230 00231 static const char HatchBrushes[][8] = { 00232 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */ 00233 { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */ 00234 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */ 00235 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */ 00236 { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */ 00237 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */ 00238 { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */ 00239 { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */ 00240 { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */ 00241 { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */ 00242 { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */ 00243 { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */ 00244 { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */ 00245 { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */ 00246 { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */ 00247 { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */ 00248 { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */ 00249 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */ 00250 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */ 00251 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */ 00252 { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */ 00253 { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */ 00254 { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */ 00255 { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */ 00256 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */ 00257 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */ 00258 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */ 00259 { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */ 00260 { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */ 00261 { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */ 00262 }; 00263 00264 GpStatus get_hatch_data(HatchStyle hatchstyle, const char **result) 00265 { 00266 if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0])) 00267 { 00268 *result = HatchBrushes[hatchstyle]; 00269 return Ok; 00270 } 00271 else 00272 return NotImplemented; 00273 } 00274 00275 /****************************************************************************** 00276 * GdipCreateHatchBrush [GDIPLUS.@] 00277 */ 00278 GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush) 00279 { 00280 TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush); 00281 00282 if(!brush) return InvalidParameter; 00283 00284 *brush = GdipAlloc(sizeof(GpHatch)); 00285 if (!*brush) return OutOfMemory; 00286 00287 (*brush)->brush.bt = BrushTypeHatchFill; 00288 (*brush)->forecol = forecol; 00289 (*brush)->backcol = backcol; 00290 (*brush)->hatchstyle = hatchstyle; 00291 TRACE("<-- %p\n", *brush); 00292 00293 return Ok; 00294 } 00295 00296 /****************************************************************************** 00297 * GdipCreateLineBrush [GDIPLUS.@] 00298 */ 00299 GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint, 00300 GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor, 00301 GpWrapMode wrap, GpLineGradient **line) 00302 { 00303 TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint), 00304 debugstr_pointf(endpoint), startcolor, endcolor, wrap, line); 00305 00306 if(!line || !startpoint || !endpoint || wrap == WrapModeClamp) 00307 return InvalidParameter; 00308 00309 if (startpoint->X == endpoint->X && startpoint->Y == endpoint->Y) 00310 return OutOfMemory; 00311 00312 *line = GdipAlloc(sizeof(GpLineGradient)); 00313 if(!*line) return OutOfMemory; 00314 00315 (*line)->brush.bt = BrushTypeLinearGradient; 00316 00317 (*line)->startpoint.X = startpoint->X; 00318 (*line)->startpoint.Y = startpoint->Y; 00319 (*line)->endpoint.X = endpoint->X; 00320 (*line)->endpoint.Y = endpoint->Y; 00321 (*line)->startcolor = startcolor; 00322 (*line)->endcolor = endcolor; 00323 (*line)->wrap = wrap; 00324 (*line)->gamma = FALSE; 00325 00326 (*line)->rect.X = (startpoint->X < endpoint->X ? startpoint->X: endpoint->X); 00327 (*line)->rect.Y = (startpoint->Y < endpoint->Y ? startpoint->Y: endpoint->Y); 00328 (*line)->rect.Width = fabs(startpoint->X - endpoint->X); 00329 (*line)->rect.Height = fabs(startpoint->Y - endpoint->Y); 00330 00331 if ((*line)->rect.Width == 0) 00332 { 00333 (*line)->rect.X -= (*line)->rect.Height / 2.0f; 00334 (*line)->rect.Width = (*line)->rect.Height; 00335 } 00336 else if ((*line)->rect.Height == 0) 00337 { 00338 (*line)->rect.Y -= (*line)->rect.Width / 2.0f; 00339 (*line)->rect.Height = (*line)->rect.Width; 00340 } 00341 00342 (*line)->blendcount = 1; 00343 (*line)->blendfac = GdipAlloc(sizeof(REAL)); 00344 (*line)->blendpos = GdipAlloc(sizeof(REAL)); 00345 00346 if (!(*line)->blendfac || !(*line)->blendpos) 00347 { 00348 GdipFree((*line)->blendfac); 00349 GdipFree((*line)->blendpos); 00350 GdipFree(*line); 00351 *line = NULL; 00352 return OutOfMemory; 00353 } 00354 00355 (*line)->blendfac[0] = 1.0f; 00356 (*line)->blendpos[0] = 1.0f; 00357 00358 (*line)->pblendcolor = NULL; 00359 (*line)->pblendpos = NULL; 00360 (*line)->pblendcount = 0; 00361 00362 TRACE("<-- %p\n", *line); 00363 00364 return Ok; 00365 } 00366 00367 GpStatus WINGDIPAPI GdipCreateLineBrushI(GDIPCONST GpPoint* startpoint, 00368 GDIPCONST GpPoint* endpoint, ARGB startcolor, ARGB endcolor, 00369 GpWrapMode wrap, GpLineGradient **line) 00370 { 00371 GpPointF stF; 00372 GpPointF endF; 00373 00374 TRACE("(%p, %p, %x, %x, %d, %p)\n", startpoint, endpoint, 00375 startcolor, endcolor, wrap, line); 00376 00377 if(!startpoint || !endpoint) 00378 return InvalidParameter; 00379 00380 stF.X = (REAL)startpoint->X; 00381 stF.Y = (REAL)startpoint->Y; 00382 endF.X = (REAL)endpoint->X; 00383 endF.Y = (REAL)endpoint->Y; 00384 00385 return GdipCreateLineBrush(&stF, &endF, startcolor, endcolor, wrap, line); 00386 } 00387 00388 GpStatus WINGDIPAPI GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect, 00389 ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap, 00390 GpLineGradient **line) 00391 { 00392 GpPointF start, end; 00393 GpStatus stat; 00394 00395 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode, 00396 wrap, line); 00397 00398 if(!line || !rect) 00399 return InvalidParameter; 00400 00401 switch (mode) 00402 { 00403 case LinearGradientModeHorizontal: 00404 start.X = rect->X; 00405 start.Y = rect->Y; 00406 end.X = rect->X + rect->Width; 00407 end.Y = rect->Y; 00408 break; 00409 case LinearGradientModeVertical: 00410 start.X = rect->X; 00411 start.Y = rect->Y; 00412 end.X = rect->X; 00413 end.Y = rect->Y + rect->Height; 00414 break; 00415 case LinearGradientModeForwardDiagonal: 00416 start.X = rect->X; 00417 start.Y = rect->Y; 00418 end.X = rect->X + rect->Width; 00419 end.Y = rect->Y + rect->Height; 00420 break; 00421 case LinearGradientModeBackwardDiagonal: 00422 start.X = rect->X + rect->Width; 00423 start.Y = rect->Y; 00424 end.X = rect->X; 00425 end.Y = rect->Y + rect->Height; 00426 break; 00427 default: 00428 return InvalidParameter; 00429 } 00430 00431 stat = GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line); 00432 00433 if (stat == Ok) 00434 (*line)->rect = *rect; 00435 00436 return stat; 00437 } 00438 00439 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect, 00440 ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap, 00441 GpLineGradient **line) 00442 { 00443 GpRectF rectF; 00444 00445 TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode, 00446 wrap, line); 00447 00448 rectF.X = (REAL) rect->X; 00449 rectF.Y = (REAL) rect->Y; 00450 rectF.Width = (REAL) rect->Width; 00451 rectF.Height = (REAL) rect->Height; 00452 00453 return GdipCreateLineBrushFromRect(&rectF, startcolor, endcolor, mode, wrap, line); 00454 } 00455 00456 /****************************************************************************** 00457 * GdipCreateLineBrushFromRectWithAngle [GDIPLUS.@] 00458 */ 00459 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect, 00460 ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap, 00461 GpLineGradient **line) 00462 { 00463 GpStatus stat; 00464 LinearGradientMode mode; 00465 REAL width, height, exofs, eyofs; 00466 REAL sin_angle, cos_angle, sin_cos_angle; 00467 00468 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable, 00469 wrap, line); 00470 00471 sin_angle = sinf(deg2rad(angle)); 00472 cos_angle = cosf(deg2rad(angle)); 00473 sin_cos_angle = sin_angle * cos_angle; 00474 00475 if (isAngleScalable) 00476 { 00477 width = height = 1.0; 00478 } 00479 else 00480 { 00481 width = rect->Width; 00482 height = rect->Height; 00483 } 00484 00485 if (sin_cos_angle >= 0) 00486 mode = LinearGradientModeForwardDiagonal; 00487 else 00488 mode = LinearGradientModeBackwardDiagonal; 00489 00490 stat = GdipCreateLineBrushFromRect(rect, startcolor, endcolor, mode, wrap, line); 00491 00492 if (stat == Ok) 00493 { 00494 if (sin_cos_angle >= 0) 00495 { 00496 exofs = width * sin_cos_angle + height * cos_angle * cos_angle; 00497 eyofs = width * sin_angle * sin_angle + height * sin_cos_angle; 00498 } 00499 else 00500 { 00501 exofs = width * sin_angle * sin_angle + height * sin_cos_angle; 00502 eyofs = -width * sin_cos_angle + height * sin_angle * sin_angle; 00503 } 00504 00505 if (isAngleScalable) 00506 { 00507 exofs = exofs * rect->Width; 00508 eyofs = eyofs * rect->Height; 00509 } 00510 00511 if (sin_angle >= 0) 00512 { 00513 (*line)->endpoint.X = rect->X + exofs; 00514 (*line)->endpoint.Y = rect->Y + eyofs; 00515 } 00516 else 00517 { 00518 (*line)->endpoint.X = (*line)->startpoint.X; 00519 (*line)->endpoint.Y = (*line)->startpoint.Y; 00520 (*line)->startpoint.X = rect->X + exofs; 00521 (*line)->startpoint.Y = rect->Y + eyofs; 00522 } 00523 } 00524 00525 return stat; 00526 } 00527 00528 GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect, 00529 ARGB startcolor, ARGB endcolor, REAL angle, BOOL isAngleScalable, GpWrapMode wrap, 00530 GpLineGradient **line) 00531 { 00532 TRACE("(%p, %x, %x, %.2f, %d, %d, %p)\n", rect, startcolor, endcolor, angle, isAngleScalable, 00533 wrap, line); 00534 00535 return GdipCreateLineBrushFromRectI(rect, startcolor, endcolor, LinearGradientModeForwardDiagonal, 00536 wrap, line); 00537 } 00538 00539 static GpStatus create_path_gradient(GpPath *path, ARGB centercolor, GpPathGradient **grad) 00540 { 00541 GpRectF bounds; 00542 GpStatus stat; 00543 00544 if(!path || !grad) 00545 return InvalidParameter; 00546 00547 if (path->pathdata.Count < 2) 00548 return OutOfMemory; 00549 00550 GdipGetPathWorldBounds(path, &bounds, NULL, NULL); 00551 00552 *grad = GdipAlloc(sizeof(GpPathGradient)); 00553 if (!*grad) 00554 { 00555 return OutOfMemory; 00556 } 00557 00558 stat = GdipCreateMatrix(&(*grad)->transform); 00559 if (stat != Ok) 00560 { 00561 GdipFree(*grad); 00562 return stat; 00563 } 00564 00565 (*grad)->blendfac = GdipAlloc(sizeof(REAL)); 00566 (*grad)->blendpos = GdipAlloc(sizeof(REAL)); 00567 (*grad)->surroundcolors = GdipAlloc(sizeof(ARGB)); 00568 if(!(*grad)->blendfac || !(*grad)->blendpos || !(*grad)->surroundcolors){ 00569 GdipDeleteMatrix((*grad)->transform); 00570 GdipFree((*grad)->blendfac); 00571 GdipFree((*grad)->blendpos); 00572 GdipFree((*grad)->surroundcolors); 00573 GdipFree(*grad); 00574 *grad = NULL; 00575 return OutOfMemory; 00576 } 00577 (*grad)->blendfac[0] = 1.0; 00578 (*grad)->blendpos[0] = 1.0; 00579 (*grad)->blendcount = 1; 00580 00581 (*grad)->path = path; 00582 00583 (*grad)->brush.bt = BrushTypePathGradient; 00584 (*grad)->centercolor = centercolor; 00585 (*grad)->wrap = WrapModeClamp; 00586 (*grad)->gamma = FALSE; 00587 /* FIXME: this should be set to the "centroid" of the path by default */ 00588 (*grad)->center.X = bounds.X + bounds.Width / 2; 00589 (*grad)->center.Y = bounds.Y + bounds.Height / 2; 00590 (*grad)->focus.X = 0.0; 00591 (*grad)->focus.Y = 0.0; 00592 (*grad)->surroundcolors[0] = 0xffffffff; 00593 (*grad)->surroundcolorcount = 1; 00594 00595 TRACE("<-- %p\n", *grad); 00596 00597 return Ok; 00598 } 00599 00600 GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF* points, 00601 INT count, GpWrapMode wrap, GpPathGradient **grad) 00602 { 00603 GpStatus stat; 00604 GpPath *path; 00605 00606 TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad); 00607 00608 if(!grad) 00609 return InvalidParameter; 00610 00611 if(!points || count <= 0) 00612 return OutOfMemory; 00613 00614 stat = GdipCreatePath(FillModeAlternate, &path); 00615 00616 if (stat == Ok) 00617 { 00618 stat = GdipAddPathLine2(path, points, count); 00619 00620 if (stat == Ok) 00621 stat = create_path_gradient(path, 0xff000000, grad); 00622 00623 if (stat != Ok) 00624 GdipDeletePath(path); 00625 } 00626 00627 if (stat == Ok) 00628 (*grad)->wrap = wrap; 00629 00630 return stat; 00631 } 00632 00633 GpStatus WINGDIPAPI GdipCreatePathGradientI(GDIPCONST GpPoint* points, 00634 INT count, GpWrapMode wrap, GpPathGradient **grad) 00635 { 00636 GpStatus stat; 00637 GpPath *path; 00638 00639 TRACE("(%p, %d, %d, %p)\n", points, count, wrap, grad); 00640 00641 if(!grad) 00642 return InvalidParameter; 00643 00644 if(!points || count <= 0) 00645 return OutOfMemory; 00646 00647 stat = GdipCreatePath(FillModeAlternate, &path); 00648 00649 if (stat == Ok) 00650 { 00651 stat = GdipAddPathLine2I(path, points, count); 00652 00653 if (stat == Ok) 00654 stat = create_path_gradient(path, 0xff000000, grad); 00655 00656 if (stat != Ok) 00657 GdipDeletePath(path); 00658 } 00659 00660 if (stat == Ok) 00661 (*grad)->wrap = wrap; 00662 00663 return stat; 00664 } 00665 00666 /****************************************************************************** 00667 * GdipCreatePathGradientFromPath [GDIPLUS.@] 00668 */ 00669 GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath* path, 00670 GpPathGradient **grad) 00671 { 00672 GpStatus stat; 00673 GpPath *new_path; 00674 00675 TRACE("(%p, %p)\n", path, grad); 00676 00677 if(!grad) 00678 return InvalidParameter; 00679 00680 if (!path) 00681 return OutOfMemory; 00682 00683 stat = GdipClonePath((GpPath*)path, &new_path); 00684 00685 if (stat == Ok) 00686 { 00687 stat = create_path_gradient(new_path, 0xffffffff, grad); 00688 00689 if (stat != Ok) 00690 GdipDeletePath(new_path); 00691 } 00692 00693 return stat; 00694 } 00695 00696 /****************************************************************************** 00697 * GdipCreateSolidFill [GDIPLUS.@] 00698 */ 00699 GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf) 00700 { 00701 TRACE("(%x, %p)\n", color, sf); 00702 00703 if(!sf) return InvalidParameter; 00704 00705 *sf = GdipAlloc(sizeof(GpSolidFill)); 00706 if (!*sf) return OutOfMemory; 00707 00708 (*sf)->brush.bt = BrushTypeSolidColor; 00709 (*sf)->color = color; 00710 00711 TRACE("<-- %p\n", *sf); 00712 00713 return Ok; 00714 } 00715 00716 /****************************************************************************** 00717 * GdipCreateTexture [GDIPLUS.@] 00718 * 00719 * PARAMS 00720 * image [I] image to use 00721 * wrapmode [I] optional 00722 * texture [O] pointer to the resulting texturebrush 00723 * 00724 * RETURNS 00725 * SUCCESS: Ok 00726 * FAILURE: element of GpStatus 00727 */ 00728 GpStatus WINGDIPAPI GdipCreateTexture(GpImage *image, GpWrapMode wrapmode, 00729 GpTexture **texture) 00730 { 00731 UINT width, height; 00732 GpImageAttributes *attributes; 00733 GpStatus stat; 00734 00735 TRACE("%p, %d %p\n", image, wrapmode, texture); 00736 00737 if (!(image && texture)) 00738 return InvalidParameter; 00739 00740 stat = GdipGetImageWidth(image, &width); 00741 if (stat != Ok) return stat; 00742 stat = GdipGetImageHeight(image, &height); 00743 if (stat != Ok) return stat; 00744 00745 stat = GdipCreateImageAttributes(&attributes); 00746 00747 if (stat == Ok) 00748 { 00749 attributes->wrap = wrapmode; 00750 00751 stat = GdipCreateTextureIA(image, attributes, 0, 0, width, height, 00752 texture); 00753 00754 GdipDisposeImageAttributes(attributes); 00755 } 00756 00757 return stat; 00758 } 00759 00760 /****************************************************************************** 00761 * GdipCreateTexture2 [GDIPLUS.@] 00762 */ 00763 GpStatus WINGDIPAPI GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode, 00764 REAL x, REAL y, REAL width, REAL height, GpTexture **texture) 00765 { 00766 GpImageAttributes *attributes; 00767 GpStatus stat; 00768 00769 TRACE("%p %d %f %f %f %f %p\n", image, wrapmode, 00770 x, y, width, height, texture); 00771 00772 stat = GdipCreateImageAttributes(&attributes); 00773 00774 if (stat == Ok) 00775 { 00776 attributes->wrap = wrapmode; 00777 00778 stat = GdipCreateTextureIA(image, attributes, x, y, width, height, 00779 texture); 00780 00781 GdipDisposeImageAttributes(attributes); 00782 } 00783 00784 return stat; 00785 } 00786 00787 /****************************************************************************** 00788 * GdipCreateTextureIA [GDIPLUS.@] 00789 * 00790 * FIXME: imageattr ignored 00791 */ 00792 GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image, 00793 GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width, 00794 REAL height, GpTexture **texture) 00795 { 00796 GpStatus status; 00797 GpImage *new_image=NULL; 00798 00799 TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height, 00800 texture); 00801 00802 if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0) 00803 return InvalidParameter; 00804 00805 *texture = NULL; 00806 00807 if(image->type != ImageTypeBitmap){ 00808 FIXME("not implemented for image type %d\n", image->type); 00809 return NotImplemented; 00810 } 00811 00812 status = GdipCloneBitmapArea(x, y, width, height, PixelFormatDontCare, (GpBitmap*)image, (GpBitmap**)&new_image); 00813 if (status != Ok) 00814 return status; 00815 00816 *texture = GdipAlloc(sizeof(GpTexture)); 00817 if (!*texture){ 00818 status = OutOfMemory; 00819 goto exit; 00820 } 00821 00822 if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){ 00823 goto exit; 00824 } 00825 00826 if (imageattr) 00827 { 00828 status = GdipCloneImageAttributes(imageattr, &(*texture)->imageattributes); 00829 } 00830 else 00831 { 00832 status = GdipCreateImageAttributes(&(*texture)->imageattributes); 00833 if (status == Ok) 00834 (*texture)->imageattributes->wrap = WrapModeTile; 00835 } 00836 if (status == Ok) 00837 { 00838 (*texture)->brush.bt = BrushTypeTextureFill; 00839 (*texture)->image = new_image; 00840 } 00841 00842 exit: 00843 if (status == Ok) 00844 { 00845 TRACE("<-- %p\n", *texture); 00846 } 00847 else 00848 { 00849 if (*texture) 00850 { 00851 GdipDeleteMatrix((*texture)->transform); 00852 GdipDisposeImageAttributes((*texture)->imageattributes); 00853 GdipFree(*texture); 00854 *texture = NULL; 00855 } 00856 GdipDisposeImage(new_image); 00857 TRACE("<-- error %u\n", status); 00858 } 00859 00860 return status; 00861 } 00862 00863 /****************************************************************************** 00864 * GdipCreateTextureIAI [GDIPLUS.@] 00865 */ 00866 GpStatus WINGDIPAPI GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageattr, 00867 INT x, INT y, INT width, INT height, GpTexture **texture) 00868 { 00869 TRACE("(%p, %p, %d, %d, %d, %d, %p)\n", image, imageattr, x, y, width, height, 00870 texture); 00871 00872 return GdipCreateTextureIA(image,imageattr,(REAL)x,(REAL)y,(REAL)width,(REAL)height,texture); 00873 } 00874 00875 GpStatus WINGDIPAPI GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode, 00876 INT x, INT y, INT width, INT height, GpTexture **texture) 00877 { 00878 GpImageAttributes *imageattr; 00879 GpStatus stat; 00880 00881 TRACE("%p %d %d %d %d %d %p\n", image, wrapmode, x, y, width, height, 00882 texture); 00883 00884 stat = GdipCreateImageAttributes(&imageattr); 00885 00886 if (stat == Ok) 00887 { 00888 imageattr->wrap = wrapmode; 00889 00890 stat = GdipCreateTextureIA(image, imageattr, x, y, width, height, texture); 00891 } 00892 00893 return stat; 00894 } 00895 00896 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type) 00897 { 00898 TRACE("(%p, %p)\n", brush, type); 00899 00900 if(!brush || !type) return InvalidParameter; 00901 00902 *type = brush->bt; 00903 00904 return Ok; 00905 } 00906 00907 GpStatus WINGDIPAPI GdipGetHatchBackgroundColor(GpHatch *brush, ARGB *backcol) 00908 { 00909 TRACE("(%p, %p)\n", brush, backcol); 00910 00911 if(!brush || !backcol) return InvalidParameter; 00912 00913 *backcol = brush->backcol; 00914 00915 return Ok; 00916 } 00917 00918 GpStatus WINGDIPAPI GdipGetHatchForegroundColor(GpHatch *brush, ARGB *forecol) 00919 { 00920 TRACE("(%p, %p)\n", brush, forecol); 00921 00922 if(!brush || !forecol) return InvalidParameter; 00923 00924 *forecol = brush->forecol; 00925 00926 return Ok; 00927 } 00928 00929 GpStatus WINGDIPAPI GdipGetHatchStyle(GpHatch *brush, HatchStyle *hatchstyle) 00930 { 00931 TRACE("(%p, %p)\n", brush, hatchstyle); 00932 00933 if(!brush || !hatchstyle) return InvalidParameter; 00934 00935 *hatchstyle = brush->hatchstyle; 00936 00937 return Ok; 00938 } 00939 00940 GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) 00941 { 00942 TRACE("(%p)\n", brush); 00943 00944 if(!brush) return InvalidParameter; 00945 00946 switch(brush->bt) 00947 { 00948 case BrushTypePathGradient: 00949 GdipDeletePath(((GpPathGradient*) brush)->path); 00950 GdipDeleteMatrix(((GpPathGradient*) brush)->transform); 00951 GdipFree(((GpPathGradient*) brush)->blendfac); 00952 GdipFree(((GpPathGradient*) brush)->blendpos); 00953 GdipFree(((GpPathGradient*) brush)->surroundcolors); 00954 GdipFree(((GpPathGradient*) brush)->pblendcolor); 00955 GdipFree(((GpPathGradient*) brush)->pblendpos); 00956 break; 00957 case BrushTypeLinearGradient: 00958 GdipFree(((GpLineGradient*)brush)->blendfac); 00959 GdipFree(((GpLineGradient*)brush)->blendpos); 00960 GdipFree(((GpLineGradient*)brush)->pblendcolor); 00961 GdipFree(((GpLineGradient*)brush)->pblendpos); 00962 break; 00963 case BrushTypeTextureFill: 00964 GdipDeleteMatrix(((GpTexture*)brush)->transform); 00965 GdipDisposeImage(((GpTexture*)brush)->image); 00966 GdipDisposeImageAttributes(((GpTexture*)brush)->imageattributes); 00967 GdipFree(((GpTexture*)brush)->bitmap_bits); 00968 break; 00969 default: 00970 break; 00971 } 00972 00973 GdipFree(brush); 00974 00975 return Ok; 00976 } 00977 00978 GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient *line, 00979 BOOL *usinggamma) 00980 { 00981 TRACE("(%p, %p)\n", line, usinggamma); 00982 00983 if(!line || !usinggamma) 00984 return InvalidParameter; 00985 00986 *usinggamma = line->gamma; 00987 00988 return Ok; 00989 } 00990 00991 GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode) 00992 { 00993 TRACE("(%p, %p)\n", brush, wrapmode); 00994 00995 if(!brush || !wrapmode) 00996 return InvalidParameter; 00997 00998 *wrapmode = brush->wrap; 00999 01000 return Ok; 01001 } 01002 01003 GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend, 01004 REAL *positions, INT count) 01005 { 01006 TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count); 01007 01008 if(!brush || !blend || !positions || count <= 0) 01009 return InvalidParameter; 01010 01011 if(count < brush->blendcount) 01012 return InsufficientBuffer; 01013 01014 memcpy(blend, brush->blendfac, count*sizeof(REAL)); 01015 if(brush->blendcount > 1){ 01016 memcpy(positions, brush->blendpos, count*sizeof(REAL)); 01017 } 01018 01019 return Ok; 01020 } 01021 01022 GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *count) 01023 { 01024 TRACE("(%p, %p)\n", brush, count); 01025 01026 if(!brush || !count) 01027 return InvalidParameter; 01028 01029 *count = brush->blendcount; 01030 01031 return Ok; 01032 } 01033 01034 GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad, 01035 GpPointF *point) 01036 { 01037 TRACE("(%p, %p)\n", grad, point); 01038 01039 if(!grad || !point) 01040 return InvalidParameter; 01041 01042 point->X = grad->center.X; 01043 point->Y = grad->center.Y; 01044 01045 return Ok; 01046 } 01047 01048 GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient *grad, 01049 GpPoint *point) 01050 { 01051 GpStatus ret; 01052 GpPointF ptf; 01053 01054 TRACE("(%p, %p)\n", grad, point); 01055 01056 if(!point) 01057 return InvalidParameter; 01058 01059 ret = GdipGetPathGradientCenterPoint(grad,&ptf); 01060 01061 if(ret == Ok){ 01062 point->X = roundr(ptf.X); 01063 point->Y = roundr(ptf.Y); 01064 } 01065 01066 return ret; 01067 } 01068 01069 GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient *grad, 01070 ARGB *colors) 01071 { 01072 TRACE("(%p,%p)\n", grad, colors); 01073 01074 if (!grad || !colors) 01075 return InvalidParameter; 01076 01077 *colors = grad->centercolor; 01078 01079 return Ok; 01080 } 01081 01082 GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad, 01083 REAL *x, REAL *y) 01084 { 01085 TRACE("(%p, %p, %p)\n", grad, x, y); 01086 01087 if(!grad || !x || !y) 01088 return InvalidParameter; 01089 01090 *x = grad->focus.X; 01091 *y = grad->focus.Y; 01092 01093 return Ok; 01094 } 01095 01096 GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad, 01097 BOOL *gamma) 01098 { 01099 TRACE("(%p, %p)\n", grad, gamma); 01100 01101 if(!grad || !gamma) 01102 return InvalidParameter; 01103 01104 *gamma = grad->gamma; 01105 01106 return Ok; 01107 } 01108 01109 GpStatus WINGDIPAPI GdipGetPathGradientPath(GpPathGradient *grad, GpPath *path) 01110 { 01111 static int calls; 01112 01113 TRACE("(%p, %p)\n", grad, path); 01114 01115 if (!(calls++)) 01116 FIXME("not implemented\n"); 01117 01118 return NotImplemented; 01119 } 01120 01121 GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad, 01122 INT *count) 01123 { 01124 TRACE("(%p, %p)\n", grad, count); 01125 01126 if(!grad || !count) 01127 return InvalidParameter; 01128 01129 *count = grad->path->pathdata.Count; 01130 01131 return Ok; 01132 } 01133 01134 GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect) 01135 { 01136 GpStatus stat; 01137 01138 TRACE("(%p, %p)\n", brush, rect); 01139 01140 if(!brush || !rect) 01141 return InvalidParameter; 01142 01143 stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL); 01144 01145 return stat; 01146 } 01147 01148 GpStatus WINGDIPAPI GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect) 01149 { 01150 GpRectF rectf; 01151 GpStatus stat; 01152 01153 TRACE("(%p, %p)\n", brush, rect); 01154 01155 if(!brush || !rect) 01156 return InvalidParameter; 01157 01158 stat = GdipGetPathGradientRect(brush, &rectf); 01159 if(stat != Ok) return stat; 01160 01161 rect->X = roundr(rectf.X); 01162 rect->Y = roundr(rectf.Y); 01163 rect->Width = roundr(rectf.Width); 01164 rect->Height = roundr(rectf.Height); 01165 01166 return Ok; 01167 } 01168 01169 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient 01170 *grad, ARGB *argb, INT *count) 01171 { 01172 INT i; 01173 01174 TRACE("(%p,%p,%p)\n", grad, argb, count); 01175 01176 if(!grad || !argb || !count || (*count < grad->path->pathdata.Count)) 01177 return InvalidParameter; 01178 01179 for (i=0; i<grad->path->pathdata.Count; i++) 01180 { 01181 if (i < grad->surroundcolorcount) 01182 argb[i] = grad->surroundcolors[i]; 01183 else 01184 argb[i] = grad->surroundcolors[grad->surroundcolorcount-1]; 01185 } 01186 01187 *count = grad->surroundcolorcount; 01188 01189 return Ok; 01190 } 01191 01192 GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT *count) 01193 { 01194 TRACE("(%p, %p)\n", brush, count); 01195 01196 if (!brush || !count) 01197 return InvalidParameter; 01198 01199 /* Yes, this actually returns the number of points in the path (which is the 01200 * required size of a buffer to get the surround colors), rather than the 01201 * number of surround colors. The real count is returned when getting the 01202 * colors. */ 01203 *count = brush->path->pathdata.Count; 01204 01205 return Ok; 01206 } 01207 01208 GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush, 01209 GpWrapMode *wrapmode) 01210 { 01211 TRACE("(%p, %p)\n", brush, wrapmode); 01212 01213 if(!brush || !wrapmode) 01214 return InvalidParameter; 01215 01216 *wrapmode = brush->wrap; 01217 01218 return Ok; 01219 } 01220 01221 GpStatus WINGDIPAPI GdipGetSolidFillColor(GpSolidFill *sf, ARGB *argb) 01222 { 01223 TRACE("(%p, %p)\n", sf, argb); 01224 01225 if(!sf || !argb) 01226 return InvalidParameter; 01227 01228 *argb = sf->color; 01229 01230 return Ok; 01231 } 01232 01233 /****************************************************************************** 01234 * GdipGetTextureImage [GDIPLUS.@] 01235 */ 01236 GpStatus WINGDIPAPI GdipGetTextureImage(GpTexture *brush, GpImage **image) 01237 { 01238 TRACE("(%p, %p)\n", brush, image); 01239 01240 if(!brush || !image) 01241 return InvalidParameter; 01242 01243 return GdipCloneImage(brush->image, image); 01244 } 01245 01246 /****************************************************************************** 01247 * GdipGetTextureTransform [GDIPLUS.@] 01248 */ 01249 GpStatus WINGDIPAPI GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix) 01250 { 01251 TRACE("(%p, %p)\n", brush, matrix); 01252 01253 if(!brush || !matrix) 01254 return InvalidParameter; 01255 01256 memcpy(matrix, brush->transform, sizeof(GpMatrix)); 01257 01258 return Ok; 01259 } 01260 01261 /****************************************************************************** 01262 * GdipGetTextureWrapMode [GDIPLUS.@] 01263 */ 01264 GpStatus WINGDIPAPI GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode) 01265 { 01266 TRACE("(%p, %p)\n", brush, wrapmode); 01267 01268 if(!brush || !wrapmode) 01269 return InvalidParameter; 01270 01271 *wrapmode = brush->imageattributes->wrap; 01272 01273 return Ok; 01274 } 01275 01276 /****************************************************************************** 01277 * GdipMultiplyTextureTransform [GDIPLUS.@] 01278 */ 01279 GpStatus WINGDIPAPI GdipMultiplyTextureTransform(GpTexture* brush, 01280 GDIPCONST GpMatrix *matrix, GpMatrixOrder order) 01281 { 01282 TRACE("(%p, %p, %d)\n", brush, matrix, order); 01283 01284 if(!brush || !matrix) 01285 return InvalidParameter; 01286 01287 return GdipMultiplyMatrix(brush->transform, matrix, order); 01288 } 01289 01290 /****************************************************************************** 01291 * GdipResetTextureTransform [GDIPLUS.@] 01292 */ 01293 GpStatus WINGDIPAPI GdipResetTextureTransform(GpTexture* brush) 01294 { 01295 TRACE("(%p)\n", brush); 01296 01297 if(!brush) 01298 return InvalidParameter; 01299 01300 return GdipSetMatrixElements(brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); 01301 } 01302 01303 /****************************************************************************** 01304 * GdipScaleTextureTransform [GDIPLUS.@] 01305 */ 01306 GpStatus WINGDIPAPI GdipScaleTextureTransform(GpTexture* brush, 01307 REAL sx, REAL sy, GpMatrixOrder order) 01308 { 01309 TRACE("(%p, %.2f, %.2f, %d)\n", brush, sx, sy, order); 01310 01311 if(!brush) 01312 return InvalidParameter; 01313 01314 return GdipScaleMatrix(brush->transform, sx, sy, order); 01315 } 01316 01317 GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, 01318 GDIPCONST REAL *factors, GDIPCONST REAL* positions, INT count) 01319 { 01320 REAL *new_blendfac, *new_blendpos; 01321 01322 TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); 01323 01324 if(!brush || !factors || !positions || count <= 0 || 01325 (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f))) 01326 return InvalidParameter; 01327 01328 new_blendfac = GdipAlloc(count * sizeof(REAL)); 01329 new_blendpos = GdipAlloc(count * sizeof(REAL)); 01330 01331 if (!new_blendfac || !new_blendpos) 01332 { 01333 GdipFree(new_blendfac); 01334 GdipFree(new_blendpos); 01335 return OutOfMemory; 01336 } 01337 01338 memcpy(new_blendfac, factors, count * sizeof(REAL)); 01339 memcpy(new_blendpos, positions, count * sizeof(REAL)); 01340 01341 GdipFree(brush->blendfac); 01342 GdipFree(brush->blendpos); 01343 01344 brush->blendcount = count; 01345 brush->blendfac = new_blendfac; 01346 brush->blendpos = new_blendpos; 01347 01348 return Ok; 01349 } 01350 01351 GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors, 01352 REAL *positions, INT count) 01353 { 01354 TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); 01355 01356 if (!brush || !factors || !positions || count <= 0) 01357 return InvalidParameter; 01358 01359 if (count < brush->blendcount) 01360 return InsufficientBuffer; 01361 01362 memcpy(factors, brush->blendfac, brush->blendcount * sizeof(REAL)); 01363 memcpy(positions, brush->blendpos, brush->blendcount * sizeof(REAL)); 01364 01365 return Ok; 01366 } 01367 01368 GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count) 01369 { 01370 TRACE("(%p, %p)\n", brush, count); 01371 01372 if (!brush || !count) 01373 return InvalidParameter; 01374 01375 *count = brush->blendcount; 01376 01377 return Ok; 01378 } 01379 01380 GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line, 01381 BOOL usegamma) 01382 { 01383 TRACE("(%p, %d)\n", line, usegamma); 01384 01385 if(!line) 01386 return InvalidParameter; 01387 01388 line->gamma = usegamma; 01389 01390 return Ok; 01391 } 01392 01393 GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus, 01394 REAL scale) 01395 { 01396 REAL factors[33]; 01397 REAL positions[33]; 01398 int num_points = 0; 01399 int i; 01400 const int precision = 16; 01401 REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */ 01402 REAL min_erf; 01403 REAL scale_erf; 01404 01405 TRACE("(%p, %0.2f, %0.2f)\n", line, focus, scale); 01406 01407 if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0) 01408 return InvalidParameter; 01409 01410 /* we want 2 standard deviations */ 01411 erf_range = 2.0 / sqrt(2); 01412 01413 /* calculate the constants we need to normalize the error function to be 01414 between 0.0 and scale over the range we need */ 01415 min_erf = erf(-erf_range); 01416 scale_erf = scale / (-2.0 * min_erf); 01417 01418 if (focus != 0.0) 01419 { 01420 positions[0] = 0.0; 01421 factors[0] = 0.0; 01422 for (i=1; i<precision; i++) 01423 { 01424 positions[i] = focus * i / precision; 01425 factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf); 01426 } 01427 num_points += precision; 01428 } 01429 01430 positions[num_points] = focus; 01431 factors[num_points] = scale; 01432 num_points += 1; 01433 01434 if (focus != 1.0) 01435 { 01436 for (i=1; i<precision; i++) 01437 { 01438 positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision)); 01439 factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf); 01440 } 01441 num_points += precision; 01442 positions[num_points-1] = 1.0; 01443 factors[num_points-1] = 0.0; 01444 } 01445 01446 return GdipSetLineBlend(line, factors, positions, num_points); 01447 } 01448 01449 GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line, 01450 GpWrapMode wrap) 01451 { 01452 TRACE("(%p, %d)\n", line, wrap); 01453 01454 if(!line || wrap == WrapModeClamp) 01455 return InvalidParameter; 01456 01457 line->wrap = wrap; 01458 01459 return Ok; 01460 } 01461 01462 GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST REAL *blend, 01463 GDIPCONST REAL *pos, INT count) 01464 { 01465 REAL *new_blendfac, *new_blendpos; 01466 01467 TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); 01468 01469 if(!brush || !blend || !pos || count <= 0 || 01470 (count >= 2 && (pos[0] != 0.0f || pos[count-1] != 1.0f))) 01471 return InvalidParameter; 01472 01473 new_blendfac = GdipAlloc(count * sizeof(REAL)); 01474 new_blendpos = GdipAlloc(count * sizeof(REAL)); 01475 01476 if (!new_blendfac || !new_blendpos) 01477 { 01478 GdipFree(new_blendfac); 01479 GdipFree(new_blendpos); 01480 return OutOfMemory; 01481 } 01482 01483 memcpy(new_blendfac, blend, count * sizeof(REAL)); 01484 memcpy(new_blendpos, pos, count * sizeof(REAL)); 01485 01486 GdipFree(brush->blendfac); 01487 GdipFree(brush->blendpos); 01488 01489 brush->blendcount = count; 01490 brush->blendfac = new_blendfac; 01491 brush->blendpos = new_blendpos; 01492 01493 return Ok; 01494 } 01495 01496 GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush, 01497 REAL focus, REAL scale) 01498 { 01499 REAL factors[3]; 01500 REAL positions[3]; 01501 int num_points = 0; 01502 01503 TRACE("(%p,%0.2f,%0.2f)\n", brush, focus, scale); 01504 01505 if (!brush) return InvalidParameter; 01506 01507 if (focus != 0.0) 01508 { 01509 factors[num_points] = 0.0; 01510 positions[num_points] = 0.0; 01511 num_points++; 01512 } 01513 01514 factors[num_points] = scale; 01515 positions[num_points] = focus; 01516 num_points++; 01517 01518 if (focus != 1.0) 01519 { 01520 factors[num_points] = 0.0; 01521 positions[num_points] = 1.0; 01522 num_points++; 01523 } 01524 01525 return GdipSetPathGradientBlend(brush, factors, positions, num_points); 01526 } 01527 01528 GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush, 01529 GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count) 01530 { 01531 ARGB *new_color; 01532 REAL *new_pos; 01533 TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); 01534 01535 if (!brush || !blend || !pos || count < 2 || 01536 pos[0] != 0.0f || pos[count-1] != 1.0f) 01537 { 01538 return InvalidParameter; 01539 } 01540 01541 new_color = GdipAlloc(count * sizeof(ARGB)); 01542 new_pos = GdipAlloc(count * sizeof(REAL)); 01543 if (!new_color || !new_pos) 01544 { 01545 GdipFree(new_color); 01546 GdipFree(new_pos); 01547 return OutOfMemory; 01548 } 01549 01550 memcpy(new_color, blend, sizeof(ARGB) * count); 01551 memcpy(new_pos, pos, sizeof(REAL) * count); 01552 01553 GdipFree(brush->pblendcolor); 01554 GdipFree(brush->pblendpos); 01555 01556 brush->pblendcolor = new_color; 01557 brush->pblendpos = new_pos; 01558 brush->pblendcount = count; 01559 01560 return Ok; 01561 } 01562 01563 GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush, 01564 ARGB *blend, REAL *pos, INT count) 01565 { 01566 TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); 01567 01568 if (count < 0) 01569 return OutOfMemory; 01570 01571 if (!brush || !blend || !pos || count < 2) 01572 return InvalidParameter; 01573 01574 if (brush->pblendcount == 0) 01575 return GenericError; 01576 01577 if (count != brush->pblendcount) 01578 { 01579 /* Native lines up the ends of each array, and copies the destination size. */ 01580 FIXME("Braindead behavior on wrong-sized buffer not implemented.\n"); 01581 return InvalidParameter; 01582 } 01583 01584 memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount); 01585 memcpy(pos, brush->pblendpos, sizeof(REAL) * brush->pblendcount); 01586 01587 return Ok; 01588 } 01589 01590 GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, 01591 INT *count) 01592 { 01593 TRACE("(%p,%p)\n", brush, count); 01594 01595 if (!brush || !count) 01596 return InvalidParameter; 01597 01598 *count = brush->pblendcount; 01599 01600 return Ok; 01601 } 01602 01603 GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad, 01604 ARGB argb) 01605 { 01606 TRACE("(%p, %x)\n", grad, argb); 01607 01608 if(!grad) 01609 return InvalidParameter; 01610 01611 grad->centercolor = argb; 01612 return Ok; 01613 } 01614 01615 GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad, 01616 GpPointF *point) 01617 { 01618 TRACE("(%p, %s)\n", grad, debugstr_pointf(point)); 01619 01620 if(!grad || !point) 01621 return InvalidParameter; 01622 01623 grad->center.X = point->X; 01624 grad->center.Y = point->Y; 01625 01626 return Ok; 01627 } 01628 01629 GpStatus WINGDIPAPI GdipSetPathGradientCenterPointI(GpPathGradient *grad, 01630 GpPoint *point) 01631 { 01632 GpPointF ptf; 01633 01634 TRACE("(%p, %p)\n", grad, point); 01635 01636 if(!point) 01637 return InvalidParameter; 01638 01639 ptf.X = (REAL)point->X; 01640 ptf.Y = (REAL)point->Y; 01641 01642 return GdipSetPathGradientCenterPoint(grad,&ptf); 01643 } 01644 01645 GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad, 01646 REAL x, REAL y) 01647 { 01648 TRACE("(%p, %.2f, %.2f)\n", grad, x, y); 01649 01650 if(!grad) 01651 return InvalidParameter; 01652 01653 grad->focus.X = x; 01654 grad->focus.Y = y; 01655 01656 return Ok; 01657 } 01658 01659 GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad, 01660 BOOL gamma) 01661 { 01662 TRACE("(%p, %d)\n", grad, gamma); 01663 01664 if(!grad) 01665 return InvalidParameter; 01666 01667 grad->gamma = gamma; 01668 01669 return Ok; 01670 } 01671 01672 GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad, 01673 REAL focus, REAL scale) 01674 { 01675 REAL factors[33]; 01676 REAL positions[33]; 01677 int num_points = 0; 01678 int i; 01679 const int precision = 16; 01680 REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */ 01681 REAL min_erf; 01682 REAL scale_erf; 01683 01684 TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale); 01685 01686 if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0) 01687 return InvalidParameter; 01688 01689 /* we want 2 standard deviations */ 01690 erf_range = 2.0 / sqrt(2); 01691 01692 /* calculate the constants we need to normalize the error function to be 01693 between 0.0 and scale over the range we need */ 01694 min_erf = erf(-erf_range); 01695 scale_erf = scale / (-2.0 * min_erf); 01696 01697 if (focus != 0.0) 01698 { 01699 positions[0] = 0.0; 01700 factors[0] = 0.0; 01701 for (i=1; i<precision; i++) 01702 { 01703 positions[i] = focus * i / precision; 01704 factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf); 01705 } 01706 num_points += precision; 01707 } 01708 01709 positions[num_points] = focus; 01710 factors[num_points] = scale; 01711 num_points += 1; 01712 01713 if (focus != 1.0) 01714 { 01715 for (i=1; i<precision; i++) 01716 { 01717 positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision)); 01718 factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf); 01719 } 01720 num_points += precision; 01721 positions[num_points-1] = 1.0; 01722 factors[num_points-1] = 0.0; 01723 } 01724 01725 return GdipSetPathGradientBlend(grad, factors, positions, num_points); 01726 } 01727 01728 GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient 01729 *grad, GDIPCONST ARGB *argb, INT *count) 01730 { 01731 ARGB *new_surroundcolors; 01732 INT i, num_colors; 01733 01734 TRACE("(%p,%p,%p)\n", grad, argb, count); 01735 01736 if(!grad || !argb || !count || (*count <= 0) || 01737 (*count > grad->path->pathdata.Count)) 01738 return InvalidParameter; 01739 01740 num_colors = *count; 01741 01742 /* If all colors are the same, only store 1 color. */ 01743 if (*count > 1) 01744 { 01745 for (i=1; i < num_colors; i++) 01746 if (argb[i] != argb[i-1]) 01747 break; 01748 01749 if (i == num_colors) 01750 num_colors = 1; 01751 } 01752 01753 new_surroundcolors = GdipAlloc(num_colors * sizeof(ARGB)); 01754 if (!new_surroundcolors) 01755 return OutOfMemory; 01756 01757 memcpy(new_surroundcolors, argb, num_colors * sizeof(ARGB)); 01758 01759 GdipFree(grad->surroundcolors); 01760 01761 grad->surroundcolors = new_surroundcolors; 01762 grad->surroundcolorcount = num_colors; 01763 01764 return Ok; 01765 } 01766 01767 GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad, 01768 GpWrapMode wrap) 01769 { 01770 TRACE("(%p, %d)\n", grad, wrap); 01771 01772 if(!grad) 01773 return InvalidParameter; 01774 01775 grad->wrap = wrap; 01776 01777 return Ok; 01778 } 01779 01780 GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad, 01781 GpMatrix *matrix) 01782 { 01783 TRACE("(%p,%p)\n", grad, matrix); 01784 01785 if (!grad || !matrix) 01786 return InvalidParameter; 01787 01788 memcpy(grad->transform, matrix, sizeof(GpMatrix)); 01789 01790 return Ok; 01791 } 01792 01793 GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad, 01794 GpMatrix *matrix) 01795 { 01796 TRACE("(%p,%p)\n", grad, matrix); 01797 01798 if (!grad || !matrix) 01799 return InvalidParameter; 01800 01801 memcpy(matrix, grad->transform, sizeof(GpMatrix)); 01802 01803 return Ok; 01804 } 01805 01806 GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad, 01807 GDIPCONST GpMatrix *matrix, GpMatrixOrder order) 01808 { 01809 TRACE("(%p,%p,%i)\n", grad, matrix, order); 01810 01811 if (!grad) 01812 return InvalidParameter; 01813 01814 return GdipMultiplyMatrix(grad->transform, matrix, order); 01815 } 01816 01817 GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad) 01818 { 01819 TRACE("(%p)\n", grad); 01820 01821 if (!grad) 01822 return InvalidParameter; 01823 01824 return GdipSetMatrixElements(grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); 01825 } 01826 01827 GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad, 01828 REAL angle, GpMatrixOrder order) 01829 { 01830 TRACE("(%p,%0.2f,%i)\n", grad, angle, order); 01831 01832 if (!grad) 01833 return InvalidParameter; 01834 01835 return GdipRotateMatrix(grad->transform, angle, order); 01836 } 01837 01838 GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad, 01839 REAL sx, REAL sy, GpMatrixOrder order) 01840 { 01841 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, sx, sy, order); 01842 01843 if (!grad) 01844 return InvalidParameter; 01845 01846 return GdipScaleMatrix(grad->transform, sx, sy, order); 01847 } 01848 01849 GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad, 01850 REAL dx, REAL dy, GpMatrixOrder order) 01851 { 01852 TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, dx, dy, order); 01853 01854 if (!grad) 01855 return InvalidParameter; 01856 01857 return GdipTranslateMatrix(grad->transform, dx, dy, order); 01858 } 01859 01860 GpStatus WINGDIPAPI GdipSetSolidFillColor(GpSolidFill *sf, ARGB argb) 01861 { 01862 TRACE("(%p, %x)\n", sf, argb); 01863 01864 if(!sf) 01865 return InvalidParameter; 01866 01867 sf->color = argb; 01868 return Ok; 01869 } 01870 01871 /****************************************************************************** 01872 * GdipSetTextureTransform [GDIPLUS.@] 01873 */ 01874 GpStatus WINGDIPAPI GdipSetTextureTransform(GpTexture *texture, 01875 GDIPCONST GpMatrix *matrix) 01876 { 01877 TRACE("(%p, %p)\n", texture, matrix); 01878 01879 if(!texture || !matrix) 01880 return InvalidParameter; 01881 01882 memcpy(texture->transform, matrix, sizeof(GpMatrix)); 01883 01884 return Ok; 01885 } 01886 01887 /****************************************************************************** 01888 * GdipSetTextureWrapMode [GDIPLUS.@] 01889 * 01890 * WrapMode not used, only stored 01891 */ 01892 GpStatus WINGDIPAPI GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode) 01893 { 01894 TRACE("(%p, %d)\n", brush, wrapmode); 01895 01896 if(!brush) 01897 return InvalidParameter; 01898 01899 brush->imageattributes->wrap = wrapmode; 01900 01901 return Ok; 01902 } 01903 01904 GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1, 01905 ARGB color2) 01906 { 01907 TRACE("(%p, %x, %x)\n", brush, color1, color2); 01908 01909 if(!brush) 01910 return InvalidParameter; 01911 01912 brush->startcolor = color1; 01913 brush->endcolor = color2; 01914 01915 return Ok; 01916 } 01917 01918 GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors) 01919 { 01920 TRACE("(%p, %p)\n", brush, colors); 01921 01922 if(!brush || !colors) 01923 return InvalidParameter; 01924 01925 colors[0] = brush->startcolor; 01926 colors[1] = brush->endcolor; 01927 01928 return Ok; 01929 } 01930 01931 /****************************************************************************** 01932 * GdipRotateTextureTransform [GDIPLUS.@] 01933 */ 01934 GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture* brush, REAL angle, 01935 GpMatrixOrder order) 01936 { 01937 TRACE("(%p, %.2f, %d)\n", brush, angle, order); 01938 01939 if(!brush) 01940 return InvalidParameter; 01941 01942 return GdipRotateMatrix(brush->transform, angle, order); 01943 } 01944 01945 GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, 01946 REAL scale) 01947 { 01948 REAL factors[3]; 01949 REAL positions[3]; 01950 int num_points = 0; 01951 01952 TRACE("(%p,%.2f,%.2f)\n", brush, focus, scale); 01953 01954 if (!brush) return InvalidParameter; 01955 01956 if (focus != 0.0) 01957 { 01958 factors[num_points] = 0.0; 01959 positions[num_points] = 0.0; 01960 num_points++; 01961 } 01962 01963 factors[num_points] = scale; 01964 positions[num_points] = focus; 01965 num_points++; 01966 01967 if (focus != 1.0) 01968 { 01969 factors[num_points] = 0.0; 01970 positions[num_points] = 1.0; 01971 num_points++; 01972 } 01973 01974 return GdipSetLineBlend(brush, factors, positions, num_points); 01975 } 01976 01977 GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, 01978 GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count) 01979 { 01980 ARGB *new_color; 01981 REAL *new_pos; 01982 TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count); 01983 01984 if (!brush || !blend || !positions || count < 2 || 01985 positions[0] != 0.0f || positions[count-1] != 1.0f) 01986 { 01987 return InvalidParameter; 01988 } 01989 01990 new_color = GdipAlloc(count * sizeof(ARGB)); 01991 new_pos = GdipAlloc(count * sizeof(REAL)); 01992 if (!new_color || !new_pos) 01993 { 01994 GdipFree(new_color); 01995 GdipFree(new_pos); 01996 return OutOfMemory; 01997 } 01998 01999 memcpy(new_color, blend, sizeof(ARGB) * count); 02000 memcpy(new_pos, positions, sizeof(REAL) * count); 02001 02002 GdipFree(brush->pblendcolor); 02003 GdipFree(brush->pblendpos); 02004 02005 brush->pblendcolor = new_color; 02006 brush->pblendpos = new_pos; 02007 brush->pblendcount = count; 02008 02009 return Ok; 02010 } 02011 02012 GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush, 02013 ARGB *blend, REAL* positions, INT count) 02014 { 02015 if (!brush || !blend || !positions || count < 2) 02016 return InvalidParameter; 02017 02018 if (brush->pblendcount == 0) 02019 return GenericError; 02020 02021 if (count < brush->pblendcount) 02022 return InsufficientBuffer; 02023 02024 memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount); 02025 memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount); 02026 02027 return Ok; 02028 } 02029 02030 GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush, 02031 INT *count) 02032 { 02033 if (!brush || !count) 02034 return InvalidParameter; 02035 02036 *count = brush->pblendcount; 02037 02038 return Ok; 02039 } 02040 02041 GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush) 02042 { 02043 static int calls; 02044 02045 TRACE("(%p)\n", brush); 02046 02047 if(!(calls++)) 02048 FIXME("not implemented\n"); 02049 02050 return NotImplemented; 02051 } 02052 02053 GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush, 02054 GDIPCONST GpMatrix *matrix) 02055 { 02056 static int calls; 02057 02058 TRACE("(%p,%p)\n", brush, matrix); 02059 02060 if(!(calls++)) 02061 FIXME("not implemented\n"); 02062 02063 return NotImplemented; 02064 } 02065 02066 GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix) 02067 { 02068 static int calls; 02069 02070 TRACE("(%p,%p)\n", brush, matrix); 02071 02072 if(!(calls++)) 02073 FIXME("not implemented\n"); 02074 02075 return NotImplemented; 02076 } 02077 02078 GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy, 02079 GpMatrixOrder order) 02080 { 02081 static int calls; 02082 02083 TRACE("(%p,%0.2f,%0.2f,%u)\n", brush, sx, sy, order); 02084 02085 if(!(calls++)) 02086 FIXME("not implemented\n"); 02087 02088 return NotImplemented; 02089 } 02090 02091 GpStatus WINGDIPAPI GdipMultiplyLineTransform(GpLineGradient *brush, 02092 GDIPCONST GpMatrix *matrix, GpMatrixOrder order) 02093 { 02094 static int calls; 02095 02096 TRACE("(%p,%p,%u)\n", brush, matrix, order); 02097 02098 if(!(calls++)) 02099 FIXME("not implemented\n"); 02100 02101 return NotImplemented; 02102 } 02103 02104 GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush, 02105 REAL dx, REAL dy, GpMatrixOrder order) 02106 { 02107 static int calls; 02108 02109 TRACE("(%p,%f,%f,%d)\n", brush, dx, dy, order); 02110 02111 if(!(calls++)) 02112 FIXME("not implemented\n"); 02113 02114 return Ok; 02115 } 02116 02117 /****************************************************************************** 02118 * GdipTranslateTextureTransform [GDIPLUS.@] 02119 */ 02120 GpStatus WINGDIPAPI GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REAL dy, 02121 GpMatrixOrder order) 02122 { 02123 TRACE("(%p, %.2f, %.2f, %d)\n", brush, dx, dy, order); 02124 02125 if(!brush) 02126 return InvalidParameter; 02127 02128 return GdipTranslateMatrix(brush->transform, dx, dy, order); 02129 } 02130 02131 GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect) 02132 { 02133 TRACE("(%p, %p)\n", brush, rect); 02134 02135 if(!brush || !rect) 02136 return InvalidParameter; 02137 02138 *rect = brush->rect; 02139 02140 return Ok; 02141 } 02142 02143 GpStatus WINGDIPAPI GdipGetLineRectI(GpLineGradient *brush, GpRect *rect) 02144 { 02145 GpRectF rectF; 02146 GpStatus ret; 02147 02148 TRACE("(%p, %p)\n", brush, rect); 02149 02150 if(!rect) 02151 return InvalidParameter; 02152 02153 ret = GdipGetLineRect(brush, &rectF); 02154 02155 if(ret == Ok){ 02156 rect->X = roundr(rectF.X); 02157 rect->Y = roundr(rectF.Y); 02158 rect->Width = roundr(rectF.Width); 02159 rect->Height = roundr(rectF.Height); 02160 } 02161 02162 return ret; 02163 } 02164 02165 GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient* brush, 02166 REAL angle, GpMatrixOrder order) 02167 { 02168 static int calls; 02169 02170 TRACE("(%p,%0.2f,%u)\n", brush, angle, order); 02171 02172 if(!brush) 02173 return InvalidParameter; 02174 02175 if(!(calls++)) 02176 FIXME("(%p, %.2f, %d) stub\n", brush, angle, order); 02177 02178 return NotImplemented; 02179 } Generated on Sat May 26 2012 04:22:09 for ReactOS by
1.7.6.1
|