diff options
Diffstat (limited to 'backend/impress/r_gradient.c')
-rw-r--r-- | backend/impress/r_gradient.c | 387 |
1 files changed, 0 insertions, 387 deletions
diff --git a/backend/impress/r_gradient.c b/backend/impress/r_gradient.c deleted file mode 100644 index 79636fe2..00000000 --- a/backend/impress/r_gradient.c +++ /dev/null @@ -1,387 +0,0 @@ -/* imposter (OO.org Impress viewer) -** Copyright (C) 2003-2005 Gurer Ozen -** This code is free software; you can redistribute it and/or -** modify it under the terms of GNU General Public License. -*/ - -#include <config.h> -#include "common.h" -#include "internal.h" -#include <math.h> - -#define GRAD_LINEAR 0 -#define GRAD_AXIAL 1 -#define GRAD_SQUARE 2 -#define GRAD_RECTANGULAR 3 -#define GRAD_RADIAL 4 -#define GRAD_ELLIPTICAL 5 - -typedef struct Gradient_s { - int type; - ImpColor start; - int start_intensity; - ImpColor end; - int end_intensity; - int angle; - int border; - int steps; - int offset_x; - int offset_y; -} Gradient; - -typedef struct Rectangle_s { - int Left; - int Top; - int Right; - int Bottom; -} Rectangle; - -static void -poly_rotate (ImpPoint *poly, int n, int cx, int cy, double fAngle) -{ - int i; - long nX, nY; - - for (i = 0; i < n; i++) { - nX = poly->x - cx; - nY = poly->y - cy; - poly->x = (cos(fAngle) * nX + sin(fAngle) * nY) + cx; - poly->y = - (sin(fAngle)* nX - cos(fAngle) * nY) + cy; - poly++; - } -} - -static void -r_draw_gradient_simple (ImpRenderCtx *ctx, void *drw_data, Gradient *grad) -{ - Rectangle rRect = { 0, 0, ctx->pix_w - 1, ctx->pix_h - 1 }; - Rectangle aRect, aFullRect; - ImpPoint poly[4], tempoly[2]; - ImpColor gcol; - double fW, fH, fDX, fDY, fAngle; - double fScanLine, fScanInc; - long redSteps, greenSteps, blueSteps; - long nBorder; - int i, nSteps, nSteps2; - int cx, cy; - - cx = rRect.Left + (rRect.Right - rRect.Left) / 2; - cy = rRect.Top + (rRect.Bottom - rRect.Top) / 2; - - aRect = rRect; - aRect.Top--; aRect.Left--; aRect.Bottom++; aRect.Right++; - fW = rRect.Right - rRect.Left; - fH = rRect.Bottom - rRect.Top; - fAngle = (((double) grad->angle) * 3.14 / 1800.0); - fDX = fW * fabs (cos (fAngle)) + fH * fabs (sin (fAngle)); - fDY = fH * fabs (cos (fAngle)) + fW * fabs (sin (fAngle)); - fDX = (fDX - fW) * 0.5 - 0.5; - fDY = (fDY - fH) * 0.5 - 0.5; - aRect.Left -= fDX; - aRect.Right += fDX; - aRect.Top -= fDY; - aRect.Bottom += fDY; - aFullRect = aRect; - - nBorder = grad->border * (aRect.Bottom - aRect.Top) / 100; - if (grad->type == GRAD_LINEAR) { - aRect.Top += nBorder; - } else { - nBorder >>= 1; - aRect.Top += nBorder; - aRect.Bottom -= nBorder; - } - - if (aRect.Top > (aRect.Bottom - 1)) - aRect.Top = aRect.Bottom - 1; - - poly[0].x = aFullRect.Left; - poly[0].y = aFullRect.Top; - poly[1].x = aFullRect.Right; - poly[1].y = aFullRect.Top; - poly[2].x = aRect.Right; - poly[2].y = aRect.Top; - poly[3].x = aRect.Left; - poly[3].y = aRect.Top; - poly_rotate (&poly[0], 4, cx, cy, fAngle); - - redSteps = grad->end.red - grad->start.red; - greenSteps = grad->end.green - grad->start.green; - blueSteps = grad->end.blue - grad->start.blue; - nSteps = grad->steps; - if (nSteps == 0) { - long mr; - mr = aRect.Bottom - aRect.Top; - if (mr < 50) - nSteps = mr / 2; - else - nSteps = mr / 4; - mr = abs(redSteps); - if (abs(greenSteps) > mr) mr = abs(greenSteps); - if (abs(blueSteps) > mr) mr = abs(blueSteps); - if (mr < nSteps) nSteps = mr; - } - - if (grad->type == GRAD_AXIAL) { - if (nSteps & 1) nSteps++; - nSteps2 = nSteps + 2; - gcol = grad->end; - redSteps <<= 1; - greenSteps <<= 1; - blueSteps <<= 1; - } else { - nSteps2 = nSteps + 1; - gcol = grad->start; - } - - fScanLine = aRect.Top; - fScanInc = (double)(aRect.Bottom - aRect.Top) / (double)nSteps; - - for (i = 0; i < nSteps2; i++) { - // draw polygon - ctx->drw->set_fg_color(drw_data, &gcol); - ctx->drw->draw_polygon(drw_data, 1, &poly[0], 4); - // calc next polygon - aRect.Top = (long)(fScanLine += fScanInc); - if (i == nSteps) { - tempoly[0].x = aFullRect.Left; - tempoly[0].y = aFullRect.Bottom; - tempoly[1].x = aFullRect.Right; - tempoly[1].y = aFullRect.Bottom; - } else { - tempoly[0].x = aRect.Left; - tempoly[0].y = aRect.Top; - tempoly[1].x = aRect.Right; - tempoly[1].y = aRect.Top; - } - poly_rotate (&tempoly[0], 2, cx, cy, fAngle); - poly[0] = poly[3]; - poly[1] = poly[2]; - poly[2] = tempoly[1]; - poly[3] = tempoly[0]; - // calc next color - if (grad->type == GRAD_LINEAR) { - gcol.red = grad->start.red + ((redSteps * i) / nSteps2); - gcol.green = grad->start.green + ((greenSteps * i) / nSteps2); - gcol.blue = grad->start.blue + ((blueSteps * i) / nSteps2); - } else { - if (i >= nSteps) { - gcol.red = grad->end.red; - gcol.green = grad->end.green; - gcol.blue = grad->end.blue; - } else { - if (i <= (nSteps / 2)) { - gcol.red = grad->end.red - ((redSteps * i) / nSteps2); - gcol.green = grad->end.green - ((greenSteps * i) / nSteps2); - gcol.blue = grad->end.blue - ((blueSteps * i) / nSteps2); - } else { - int i2 = i - nSteps / 2; - gcol.red = grad->start.red + ((redSteps * i2) / nSteps2); - gcol.green = grad->start.green + ((greenSteps * i2) / nSteps2); - gcol.blue = grad->start.blue + ((blueSteps * i2) / nSteps2); - } - } - } - } -} - -static void -r_draw_gradient_complex (ImpRenderCtx *ctx, void *drw_data, Gradient *grad) -{ - Rectangle rRect = { 0, 0, ctx->pix_w - 1, ctx->pix_h - 1 }; - Rectangle aRect = rRect; - ImpColor gcol; - ImpPoint poly[4]; - double fAngle = (((double) grad->angle) * 3.14 / 1800.0); - long redSteps, greenSteps, blueSteps; - long nZW, nZH; - long bX, bY; - long sW, sH; - long cx, cy; - int i; - long nSteps; - double sTop, sLeft, sRight, sBottom, sInc; - int minRect; - - redSteps = grad->end.red - grad->start.red; - greenSteps = grad->end.green - grad->start.green; - blueSteps = grad->end.blue - grad->start.blue; - - if (grad->type == GRAD_SQUARE || grad->type == GRAD_RECTANGULAR) { - double fW = aRect.Right - aRect.Left; - double fH = aRect.Bottom - aRect.Top; - double fDX = fW * fabs (cos (fAngle)) + fH * fabs (sin (fAngle)); - double fDY = fH * fabs (cos (fAngle)) + fW * fabs (sin (fAngle)); - fDX = (fDX - fW) * 0.5 - 0.5; - fDY = (fDY - fH) * 0.5 - 0.5; - aRect.Left -= fDX; - aRect.Right += fDX; - aRect.Top -= fDY; - aRect.Bottom += fDY; - } - - sW = aRect.Right - aRect.Left; - sH = aRect.Bottom - aRect.Top; - - if (grad->type == GRAD_SQUARE) { - if (sW > sH) sH = sW; else sW = sH; - } else if (grad->type == GRAD_RADIAL) { - sW = 0.5 + sqrt ((double)sW*(double)sW + (double)sH*(double)sH); - sH = sW; - } else if (grad->type == GRAD_ELLIPTICAL) { - sW = 0.5 + (double)sW * 1.4142; - sH = 0.5 + (double)sH * 1.4142; - } - - nZW = (aRect.Right - aRect.Left) * grad->offset_x / 100; - nZH = (aRect.Bottom - aRect.Top) * grad->offset_y / 100; - bX = grad->border * sW / 100; - bY = grad->border * sH / 100; - cx = aRect.Left + nZW; - cy = aRect.Top + nZH; - - sW -= bX; - sH -= bY; - - aRect.Left = cx - ((aRect.Right - aRect.Left) >> 1); - aRect.Top = cy - ((aRect.Bottom - aRect.Top) >> 1); - - nSteps = grad->steps; - minRect = aRect.Right - aRect.Left; - if (aRect.Bottom - aRect.Top < minRect) minRect = aRect.Bottom - aRect.Top; - if (nSteps == 0) { - long mr; - if (minRect < 50) - nSteps = minRect / 2; - else - nSteps = minRect / 4; - mr = abs(redSteps); - if (abs(greenSteps) > mr) mr = abs(greenSteps); - if (abs(blueSteps) > mr) mr = abs(blueSteps); - if (mr < nSteps) nSteps = mr; - } - - sLeft = aRect.Left; - sTop = aRect.Top; - sRight = aRect.Right; - sBottom = aRect.Bottom; - sInc = (double) minRect / (double) nSteps * 0.5; - - gcol = grad->start; - poly[0].x = rRect.Left; - poly[0].y = rRect.Top; - poly[1].x = rRect.Right; - poly[1].y = rRect.Top; - poly[2].x = rRect.Right; - poly[2].y = rRect.Bottom; - poly[3].x = rRect.Left; - poly[3].y = rRect.Bottom; - ctx->drw->set_fg_color(drw_data, &gcol); - ctx->drw->draw_polygon(drw_data, 1, &poly[0], 4); - - for (i = 0; i < nSteps; i++) { - aRect.Left = (long) (sLeft += sInc); - aRect.Top = (long) (sTop += sInc); - aRect.Right = (long) (sRight -= sInc); - aRect.Bottom = (long) (sBottom -= sInc); - if (aRect.Bottom - aRect.Top < 2 || aRect.Right - aRect.Left < 2) - break; - - gcol.red = grad->start.red + (redSteps * (i+1) / nSteps); - gcol.green = grad->start.green + (greenSteps * (i+1) / nSteps); - gcol.blue = grad->start.blue + (blueSteps * (i+1) / nSteps); - ctx->drw->set_fg_color(drw_data, &gcol); - - if (grad->type == GRAD_RADIAL || grad->type == GRAD_ELLIPTICAL) { - ctx->drw->draw_arc(drw_data, 1, aRect.Left, aRect.Top, - aRect.Right - aRect.Left, aRect.Bottom - aRect.Top, - 0, 360); - } else { - poly[0].x = aRect.Left; - poly[0].y = aRect.Top; - poly[1].x = aRect.Right; - poly[1].y = aRect.Top; - poly[2].x = aRect.Right; - poly[2].y = aRect.Bottom; - poly[3].x = aRect.Left; - poly[3].y = aRect.Bottom; - poly_rotate (&poly[0], 4, cx, cy, fAngle); - ctx->drw->draw_polygon(drw_data, 1, &poly[0], 4); - } - } -} - -void -r_draw_gradient (ImpRenderCtx *ctx, void *drw_data, iks *node) -{ -// GdkGC *gc; - Gradient grad; - char *stil, *tmp; - iks *x; - - stil = r_get_style (ctx, node, "draw:fill-gradient-name"); - x = iks_find_with_attrib (iks_find (ctx->styles, "office:styles"), - "draw:gradient", "draw:name", stil); - if (x) { - memset (&grad, 0, sizeof (Gradient)); - grad.type = -1; - grad.offset_x = 50; - grad.offset_y = 50; - - tmp = iks_find_attrib (x, "draw:start-color"); - if (tmp) r_parse_color (tmp, &grad.start); - tmp = iks_find_attrib (x, "draw:start-intensity"); - if (tmp) { - int val = atoi (tmp); - grad.start.red = grad.start.red * val / 100; - grad.start.green = grad.start.green * val / 100; - grad.start.blue = grad.start.blue * val / 100; - } - tmp = iks_find_attrib (x, "draw:end-color"); - if (tmp) r_parse_color (tmp, &grad.end); - tmp = iks_find_attrib (x, "draw:end-intensity"); - if (tmp) { - int val = atoi (tmp); - grad.end.red = grad.end.red * val / 100; - grad.end.green = grad.end.green * val / 100; - grad.end.blue = grad.end.blue * val / 100; - } - tmp = iks_find_attrib (x, "draw:angle"); - if (tmp) grad.angle = atoi(tmp) % 3600; - tmp = iks_find_attrib (x, "draw:border"); - if (tmp) grad.border = atoi(tmp); - tmp = r_get_style (ctx, node, "draw:gradient-step-count"); - if (tmp) grad.steps = atoi (tmp); - tmp = iks_find_attrib (x, "draw:cx"); - if (tmp) grad.offset_x = atoi (tmp); - tmp = iks_find_attrib (x, "draw:cy"); - if (tmp) grad.offset_y = atoi (tmp); - tmp = iks_find_attrib (x, "draw:style"); - if (iks_strcmp (tmp, "linear") == 0) - grad.type = GRAD_LINEAR; - else if (iks_strcmp (tmp, "axial") == 0) - grad.type = GRAD_AXIAL; - else if (iks_strcmp (tmp, "radial") == 0) - grad.type = GRAD_RADIAL; - else if (iks_strcmp (tmp, "rectangular") == 0) - grad.type = GRAD_RECTANGULAR; - else if (iks_strcmp (tmp, "ellipsoid") == 0) - grad.type = GRAD_ELLIPTICAL; - else if (iks_strcmp (tmp, "square") == 0) - grad.type = GRAD_SQUARE; - - if (grad.type == -1) return; - -// gc = ctx->gc; -// ctx->gc = gdk_gc_new (ctx->d); -// gdk_gc_copy (ctx->gc, gc); - - if (grad.type == GRAD_LINEAR || grad.type == GRAD_AXIAL) - r_draw_gradient_simple (ctx, drw_data, &grad); - else - r_draw_gradient_complex (ctx, drw_data, &grad); - -// g_object_unref (ctx->gc); -// ctx->gc = gc; - } -} |