color.py :  » PDF » PyX » PyX-0.10 » pyx » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » PDF » PyX 
PyX » PyX 0.10 » pyx » color.py
# -*- coding: ISO-8859-1 -*-
#
#
# Copyright (C) 2002-2004, 2006 Jrg Lehmann <joergl@users.sourceforge.net>
# Copyright (C) 2003-2006 Michael Schindler <m-schindler@users.sourceforge.net>
# Copyright (C) 2002-2007 Andr Wobst <wobsta@users.sourceforge.net>
#
# This file is part of PyX (http://pyx.sourceforge.net/).
#
# PyX is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PyX is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyX; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

import binascii, colorsys, math, struct, warnings
import attr, style, pdfwriter

# device-dependend (nonlinear) functions for color conversion
# UCRx : [0,1] -> [-1, 1] UnderColorRemoval (removes black from c, y, m)
# BG   : [0,1] -> [0, 1]  BlackGeneration (generate the black from the nominal k-value)
# as long as we have no further knowledge we define them linearly with constants 1
def _UCRc(x): return x
def _UCRm(x): return x
def _UCRy(x): return x
def _BG(x): return x

def set(UCRc=None, UCRm=None, UCRy=None, BG=None):
    global _UCRc
    global _UCRm
    global _UCRy
    global _BG

    if UCRc is not None:
        _UCRc = UCRc
    if UCRm is not None:
        _UCRm = UCRm
    if UCRy is not None:
        _UCRy = UCRy
    if BG is not None:
        _BG = BG


class color(attr.exclusiveattr, style.strokestyle, style.fillstyle):

    """base class for all colors"""

    def __init__(self):
        attr.exclusiveattr.__init__(self, color)


clear = attr.clearclass(color)


class grey(color):

    """grey tones"""

    def __init__(self, gray):
        color.__init__(self)
        if gray<0 or gray>1: raise ValueError
        self.color = {"gray": gray}

    def processPS(self, file, writer, context, registry, bbox):
        file.write("%(gray)g setgray\n" % self.color)

    def processPDF(self, file, writer, context, registry, bbox):
        if context.strokeattr:
            file.write("%(gray)f G\n" % self.color)
        if context.fillattr:
            file.write("%(gray)f g\n" % self.color)

    def cmyk(self):
        return cmyk(0, 0, 0, 1 - self.color["gray"])

    def grey(self):
        return grey(**self.color)
    gray = grey

    def hsb(self):
        return hsb(0, 0, self.color["gray"])

    def rgb(self):
        return rgb(self.color["gray"], self.color["gray"], self.color["gray"])

    def colorspacestring(self):
        return "/DeviceGray"

    def tostring8bit(self):
        return chr(int(self.color["gray"]*255))

grey.black = grey(0.0)
grey.white = grey(1.0)
gray = grey


class rgb(color):

    """rgb colors"""

    def __init__(self, r=0.0, g=0.0, b=0.0):
        color.__init__(self)
        if r<0 or r>1 or g<0 or g>1 or b<0 or b>1: raise ValueError
        self.color = {"r": r, "g": g, "b": b}

    def processPS(self, file, writer, context, registry, bbox):
        file.write("%(r)g %(g)g %(b)g setrgbcolor\n" % self.color)

    def processPDF(self, file, writer, context, registry, bbox):
        if context.strokeattr:
            file.write("%(r)f %(g)f %(b)f RG\n" % self.color)
        if context.fillattr:
            file.write("%(r)f %(g)f %(b)f rg\n" % self.color)

    def cmyk(self):
        # conversion to cmy
        c, m, y = 1 - self.color["r"], 1 - self.color["g"], 1 - self.color["b"]
        # conversion from cmy to cmyk with device-dependent functions
        k = min([c, m, y])
        return cmyk(min(1, max(0, c - _UCRc(k))),
                    min(1, max(0, m - _UCRm(k))),
                    min(1, max(0, y - _UCRy(k))),
                    _BG(k))

    def grey(self):
        return grey(0.3*self.color["r"] + 0.59*self.color["g"] + 0.11*self.color["b"])
    gray = grey

    def hsb(self):

        values = self.color.values()
        values.sort()
        z, y, x = values
        r, g, b = self.color["r"], self.color["g"], self.color["b"]
        try:
            if r == x and g == z:
                return hsb((5 + (x-b)/(x-z)) / 6.0, (x - z) / x, x)
            elif r == x and g > z:
                return hsb((1 - (x-g)/(x-z)) / 6.0, (x - z) / x, x)
            elif g == x and b == z:
                return hsb((1 + (x-r)/(x-z)) / 6.0, (x - z) / x, x)
            elif g == x and b > z:
                return hsb((3 - (x-b)/(x-z)) / 6.0, (x - z) / x, x)
            elif b == x and r == z:
                return hsb((3 + (x-g)/(x-z)) / 6.0, (x - z) / x, x)
            elif b == x and r > z:
                return hsb((5 - (x-r)/(x-z)) / 6.0, (x - z) / x, x)
            else:
                raise ValueError
        except ZeroDivisionError:
            return hsb(0, 0, x)

    def rgb(self):
        return rgb(**self.color)

    def colorspacestring(self):
        return "/DeviceRGB"

    def tostring8bit(self):
        return struct.pack("BBB", int(self.color["r"]*255), int(self.color["g"]*255), int(self.color["b"]*255))

    def tohexstring(self, cssstrip=1, addhash=1):
        hexstring = binascii.b2a_hex(self.to8bitstring())
        if cssstrip and hexstring[0] == hexstring[1] and hexstring[2] == hexstring[3] and hexstring[4] == hexstring[5]:
            hexstring = "".join([hexstring[0], hexstring[1], hexstring[2]])
        if addhash:
            hexstring = "#" + hexstring
        return hexstring


def rgbfromhexstring(hexstring):
    hexstring = hexstring.strip().lstrip("#")
    if len(hexstring) == 3:
        hexstring = "".join([hexstring[0], hexstring[0], hexstring[1], hexstring[1], hexstring[2], hexstring[2]])
    elif len(hexstring) != 6:
        raise ValueError("3 or 6 digit hex number expected (with optional leading hash character)")
    return rgb(*[value/255.0 for value in struct.unpack("BBB", binascii.a2b_hex(hexstring))])

rgb.red   = rgb(1, 0, 0)
rgb.green = rgb(0, 1, 0)
rgb.blue  = rgb(0, 0, 1)
rgb.white = rgb(1, 1, 1)
rgb.black = rgb(0, 0, 0)


class hsb(color):

    """hsb colors"""

    def __init__(self, h=0.0, s=0.0, b=0.0):
        color.__init__(self)
        if h<0 or h>1 or s<0 or s>1 or b<0 or b>1: raise ValueError
        self.color = {"h": h, "s": s, "b": b}

    def processPS(self, file, writer, context, registry, bbox):
        file.write("%(h)g %(s)g %(b)g sethsbcolor\n" % self.color)

    def processPDF(self, file, writer, context, registry, bbox):
        r, g, b = colorsys.hsv_to_rgb(self.color["h"], self.color["s"], self.color["b"])
        rgb(r, g, b).processPDF(file, writer, context, registry, bbox)

    def cmyk(self):
        return self.rgb().cmyk()

    def grey(self):
        return self.rgb().grey()
    gray = grey

    def hsb(self):
        return hsb(**self.color)

    def rgb(self):
        h, s, b = self.color["h"], self.color["s"], self.color["b"]
        i = int(6*h)
        f = 6*h - i
        m, n, k = 1 - s, 1 - s*f, 1 - s*(1-f)
        if i == 1:
            return rgb(b*n, b, b*m)
        elif i == 2:
            return rgb(b*m, b, b*k)
        elif i == 3:
            return rgb(b*m, b*n, b)
        elif i == 4:
            return rgb(b*k, b*m, b)
        elif i == 5:
            return rgb(b, b*m, b*n)
        else:
            return rgb(b, b*k, b*m)

    def colorspacestring(self):
        raise RuntimeError("colorspace string not available for hsb colors")


class cmyk(color):

    """cmyk colors"""

    def __init__(self, c=0.0, m=0.0, y=0.0, k=0.0):
        color.__init__(self)
        if c<0 or c>1 or m<0 or m>1 or y<0 or y>1 or k<0 or k>1: raise ValueError
        self.color = {"c": c, "m": m, "y": y, "k": k}

    def processPS(self, file, writer, context, registry, bbox):
        file.write("%(c)g %(m)g %(y)g %(k)g setcmykcolor\n" % self.color)

    def processPDF(self, file, writer, context, registry, bbox):
        if context.strokeattr:
            file.write("%(c)f %(m)f %(y)f %(k)f K\n" % self.color)
        if context.fillattr:
            file.write("%(c)f %(m)f %(y)f %(k)f k\n" % self.color)

    def cmyk(self):
        return cmyk(**self.color)

    def grey(self):
        return grey(1 - min([1, 0.3*self.color["c"] + 0.59*self.color["m"] +
                                0.11*self.color["y"] + self.color["k"]]))
    gray = grey

    def hsb(self):
        return self.rgb().hsb()

    def rgb(self):
        # conversion to cmy:
        c = min(1, self.color["c"] + self.color["k"])
        m = min(1, self.color["m"] + self.color["k"])
        y = min(1, self.color["y"] + self.color["k"])
        # conversion from cmy to rgb:
        return rgb(1 - c, 1 - m, 1 - y)

    def colorspacestring(self):
        return "/DeviceCMYK"

    def tostring8bit(self):
        return struct.pack("BBBB", int(self.color["c"]*255), int(self.color["m"]*255), int(self.color["y"]*255), int(self.color["k"]*255))

cmyk.GreenYellow    = cmyk(0.15, 0, 0.69, 0)
cmyk.Yellow         = cmyk(0, 0, 1, 0)
cmyk.Goldenrod      = cmyk(0, 0.10, 0.84, 0)
cmyk.Dandelion      = cmyk(0, 0.29, 0.84, 0)
cmyk.Apricot        = cmyk(0, 0.32, 0.52, 0)
cmyk.Peach          = cmyk(0, 0.50, 0.70, 0)
cmyk.Melon          = cmyk(0, 0.46, 0.50, 0)
cmyk.YellowOrange   = cmyk(0, 0.42, 1, 0)
cmyk.Orange         = cmyk(0, 0.61, 0.87, 0)
cmyk.BurntOrange    = cmyk(0, 0.51, 1, 0)
cmyk.Bittersweet    = cmyk(0, 0.75, 1, 0.24)
cmyk.RedOrange      = cmyk(0, 0.77, 0.87, 0)
cmyk.Mahogany       = cmyk(0, 0.85, 0.87, 0.35)
cmyk.Maroon         = cmyk(0, 0.87, 0.68, 0.32)
cmyk.BrickRed       = cmyk(0, 0.89, 0.94, 0.28)
cmyk.Red            = cmyk(0, 1, 1, 0)
cmyk.OrangeRed      = cmyk(0, 1, 0.50, 0)
cmyk.RubineRed      = cmyk(0, 1, 0.13, 0)
cmyk.WildStrawberry = cmyk(0, 0.96, 0.39, 0)
cmyk.Salmon         = cmyk(0, 0.53, 0.38, 0)
cmyk.CarnationPink  = cmyk(0, 0.63, 0, 0)
cmyk.Magenta        = cmyk(0, 1, 0, 0)
cmyk.VioletRed      = cmyk(0, 0.81, 0, 0)
cmyk.Rhodamine      = cmyk(0, 0.82, 0, 0)
cmyk.Mulberry       = cmyk(0.34, 0.90, 0, 0.02)
cmyk.RedViolet      = cmyk(0.07, 0.90, 0, 0.34)
cmyk.Fuchsia        = cmyk(0.47, 0.91, 0, 0.08)
cmyk.Lavender       = cmyk(0, 0.48, 0, 0)
cmyk.Thistle        = cmyk(0.12, 0.59, 0, 0)
cmyk.Orchid         = cmyk(0.32, 0.64, 0, 0)
cmyk.DarkOrchid     = cmyk(0.40, 0.80, 0.20, 0)
cmyk.Purple         = cmyk(0.45, 0.86, 0, 0)
cmyk.Plum           = cmyk(0.50, 1, 0, 0)
cmyk.Violet         = cmyk(0.79, 0.88, 0, 0)
cmyk.RoyalPurple    = cmyk(0.75, 0.90, 0, 0)
cmyk.BlueViolet     = cmyk(0.86, 0.91, 0, 0.04)
cmyk.Periwinkle     = cmyk(0.57, 0.55, 0, 0)
cmyk.CadetBlue      = cmyk(0.62, 0.57, 0.23, 0)
cmyk.CornflowerBlue = cmyk(0.65, 0.13, 0, 0)
cmyk.MidnightBlue   = cmyk(0.98, 0.13, 0, 0.43)
cmyk.NavyBlue       = cmyk(0.94, 0.54, 0, 0)
cmyk.RoyalBlue      = cmyk(1, 0.50, 0, 0)
cmyk.Blue           = cmyk(1, 1, 0, 0)
cmyk.Cerulean       = cmyk(0.94, 0.11, 0, 0)
cmyk.Cyan           = cmyk(1, 0, 0, 0)
cmyk.ProcessBlue    = cmyk(0.96, 0, 0, 0)
cmyk.SkyBlue        = cmyk(0.62, 0, 0.12, 0)
cmyk.Turquoise      = cmyk(0.85, 0, 0.20, 0)
cmyk.TealBlue       = cmyk(0.86, 0, 0.34, 0.02)
cmyk.Aquamarine     = cmyk(0.82, 0, 0.30, 0)
cmyk.BlueGreen      = cmyk(0.85, 0, 0.33, 0)
cmyk.Emerald        = cmyk(1, 0, 0.50, 0)
cmyk.JungleGreen    = cmyk(0.99, 0, 0.52, 0)
cmyk.SeaGreen       = cmyk(0.69, 0, 0.50, 0)
cmyk.Green          = cmyk(1, 0, 1, 0)
cmyk.ForestGreen    = cmyk(0.91, 0, 0.88, 0.12)
cmyk.PineGreen      = cmyk(0.92, 0, 0.59, 0.25)
cmyk.LimeGreen      = cmyk(0.50, 0, 1, 0)
cmyk.YellowGreen    = cmyk(0.44, 0, 0.74, 0)
cmyk.SpringGreen    = cmyk(0.26, 0, 0.76, 0)
cmyk.OliveGreen     = cmyk(0.64, 0, 0.95, 0.40)
cmyk.RawSienna      = cmyk(0, 0.72, 1, 0.45)
cmyk.Sepia          = cmyk(0, 0.83, 1, 0.70)
cmyk.Brown          = cmyk(0, 0.81, 1, 0.60)
cmyk.Tan            = cmyk(0.14, 0.42, 0.56, 0)
cmyk.Gray           = cmyk(0, 0, 0, 0.50)
cmyk.Grey           = cmyk.Gray
cmyk.Black          = cmyk(0, 0, 0, 1)
cmyk.White          = cmyk(0, 0, 0, 0)
cmyk.white          = cmyk.White
cmyk.black          = cmyk.Black

class palette(attr.changelist):
    """color palettes

    A color palette is a discrete, ordered list of colors"""

palette.clear = attr.clearclass(palette)


class gradient(attr.changeattr):

    """base class for color gradients

    A gradient is a continuous collection of colors with a single parameter ranging from 0 to 1
    to address them"""

    def getcolor(self, param):
        """return color corresponding to param"""
        pass

    def select(self, index, n_indices):
        """return a color corresponding to an index out of n_indices"""
        if n_indices == 1:
            param = 0
        else:
            param = index / (n_indices - 1.0)
        return self.getcolor(param)

gradient.clear = attr.clearclass(gradient)


class lineargradient(gradient):

    """collection of two colors for a linear transition between them"""

    def __init__(self, mincolor, maxcolor):
        if mincolor.__class__ != maxcolor.__class__:
            raise ValueError
        self.colorclass = mincolor.__class__
        self.mincolor = mincolor
        self.maxcolor = maxcolor

    def getcolor(self, param):
        colordict = {}
        for key in self.mincolor.color.keys():
            colordict[key] = param * self.maxcolor.color[key] + (1 - param) * self.mincolor.color[key]
        return self.colorclass(**colordict)


class functiongradient(gradient):

    """collection of colors for an arbitray non-linear transition between them

    parameters:
    functions: a dictionary for the color values
    type:      a string indicating the color class
    """

    def __init__(self, functions, cls):
        self.functions = functions
        self.cls = cls

    def getcolor(self, param):
        colordict = {}
        for key in self.functions.keys():
            colordict[key] = self.functions[key](param)
        return self.cls(**colordict)


gradient.Gray           = lineargradient(gray.white, gray.black)
gradient.Grey           = gradient.Gray
gradient.ReverseGray    = lineargradient(gray.black, gray.white)
gradient.ReverseGrey    = gradient.ReverseGray
gradient.BlackYellow    = functiongradient({ # compare this with reversegray above
    "r":(lambda x: 2*x*(1-x)**5 + 3.5*x**2*(1-x)**3 + 2.1*x*x*(1-x)**2 + 3.0*x**3*(1-x)**2 + x**0.5*(1-(1-x)**2)),
    "g":(lambda x: 1.5*x**2*(1-x)**3 - 0.8*x**3*(1-x)**2 + 2.0*x**4*(1-x) + x**4),
    "b":(lambda x: 5*x*(1-x)**5 - 0.5*x**2*(1-x)**3 + 0.3*x*x*(1-x)**2 + 5*x**3*(1-x)**2 + 0.5*x**6)},
    rgb)
gradient.RedGreen       = lineargradient(rgb.red, rgb.green)
gradient.RedBlue        = lineargradient(rgb.red, rgb.blue)
gradient.GreenRed       = lineargradient(rgb.green, rgb.red)
gradient.GreenBlue      = lineargradient(rgb.green, rgb.blue)
gradient.BlueRed        = lineargradient(rgb.blue, rgb.red)
gradient.BlueGreen      = lineargradient(rgb.blue, rgb.green)
gradient.RedBlack       = lineargradient(rgb.red, rgb.black)
gradient.BlackRed       = lineargradient(rgb.black, rgb.red)
gradient.RedWhite       = lineargradient(rgb.red, rgb.white)
gradient.WhiteRed       = lineargradient(rgb.white, rgb.red)
gradient.GreenBlack     = lineargradient(rgb.green, rgb.black)
gradient.BlackGreen     = lineargradient(rgb.black, rgb.green)
gradient.GreenWhite     = lineargradient(rgb.green, rgb.white)
gradient.WhiteGreen     = lineargradient(rgb.white, rgb.green)
gradient.BlueBlack      = lineargradient(rgb.blue, rgb.black)
gradient.BlackBlue      = lineargradient(rgb.black, rgb.blue)
gradient.BlueWhite      = lineargradient(rgb.blue, rgb.white)
gradient.WhiteBlue      = lineargradient(rgb.white, rgb.blue)
gradient.Rainbow        = lineargradient(hsb(0, 1, 1), hsb(2.0/3.0, 1, 1))
gradient.ReverseRainbow = lineargradient(hsb(2.0/3.0, 1, 1), hsb(0, 1, 1))
gradient.Hue            = lineargradient(hsb(0, 1, 1), hsb(1, 1, 1))
gradient.ReverseHue     = lineargradient(hsb(1, 1, 1), hsb(0, 1, 1))


class PDFextgstate(pdfwriter.PDFobject):

    def __init__(self, name, extgstate, registry):
        pdfwriter.PDFobject.__init__(self, "extgstate", name)
        registry.addresource("ExtGState", name, self)
        self.name = name
        self.extgstate = extgstate

    def write(self, file, writer, registry):
        file.write("%s\n" % self.extgstate)


class transparency(attr.exclusiveattr, style.strokestyle, style.fillstyle):

    def __init__(self, value):
        self.value = 1-value
        attr.exclusiveattr.__init__(self, transparency)

    def processPS(self, file, writer, context, registry, bbox):
        warnings.warn("Transparency not available in PostScript, proprietary ghostscript extension code inserted.")
        file.write("%f .setshapealpha\n" % self.value)

    def processPDF(self, file, writer, context, registry, bbox):
        if context.strokeattr and context.fillattr:
            registry.add(PDFextgstate("Transparency-%f" % self.value,
                                      "<< /Type /ExtGState /CA %f /ca %f >>" % (self.value, self.value), registry))
            file.write("/Transparency-%f gs\n" % self.value)
        elif context.strokeattr:
            registry.add(PDFextgstate("Transparency-Stroke-%f" % self.value,
                                      "<< /Type /ExtGState /CA %f >>" % self.value, registry))
            file.write("/Transparency-Stroke-%f gs\n" % self.value)
        elif context.fillattr:
            registry.add(PDFextgstate("Transparency-Fill-%f" % self.value,
                                      "<< /Type /ExtGState /ca %f >>" % self.value, registry))
            file.write("/Transparency-Fill-%f gs\n" % self.value)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.