HPGSTranslator: Remove from the tree.
Not included in the build and not referenced anywhere else. Now lives at HaikuArchives.
This commit is contained in:
@@ -594,7 +594,6 @@ rule ArchitectureSetupWarnings architecture
|
|||||||
EnableWerror src add-ons translators bmp ;
|
EnableWerror src add-ons translators bmp ;
|
||||||
EnableWerror src add-ons translators exr ;
|
EnableWerror src add-ons translators exr ;
|
||||||
EnableWerror src add-ons translators gif ;
|
EnableWerror src add-ons translators gif ;
|
||||||
# EnableWerror src add-ons translators hpgs ;
|
|
||||||
EnableWerror src add-ons translators hvif ;
|
EnableWerror src add-ons translators hvif ;
|
||||||
EnableWerror src add-ons translators ico ;
|
EnableWerror src add-ons translators ico ;
|
||||||
EnableWerror src add-ons translators jpeg ;
|
EnableWerror src add-ons translators jpeg ;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ SubDir HAIKU_TOP src add-ons translators ;
|
|||||||
SubInclude HAIKU_TOP src add-ons translators bmp ;
|
SubInclude HAIKU_TOP src add-ons translators bmp ;
|
||||||
SubInclude HAIKU_TOP src add-ons translators exr ;
|
SubInclude HAIKU_TOP src add-ons translators exr ;
|
||||||
SubInclude HAIKU_TOP src add-ons translators gif ;
|
SubInclude HAIKU_TOP src add-ons translators gif ;
|
||||||
SubInclude HAIKU_TOP src add-ons translators hpgs ;
|
|
||||||
SubInclude HAIKU_TOP src add-ons translators hvif ;
|
SubInclude HAIKU_TOP src add-ons translators hvif ;
|
||||||
SubInclude HAIKU_TOP src add-ons translators ico ;
|
SubInclude HAIKU_TOP src add-ons translators ico ;
|
||||||
SubInclude HAIKU_TOP src add-ons translators jpeg ;
|
SubInclude HAIKU_TOP src add-ons translators jpeg ;
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007, Jérôme Duval. All rights reserved.
|
|
||||||
* Copyright 2005-2007, Axel Dörfler, [email protected]. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "ConfigView.h"
|
|
||||||
#include "HPGSTranslator.h"
|
|
||||||
|
|
||||||
#include <Catalog.h>
|
|
||||||
#include <CheckBox.h>
|
|
||||||
#include <StringView.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
|
||||||
#define B_TRANSLATION_CONTEXT "ConfigView"
|
|
||||||
|
|
||||||
|
|
||||||
ConfigView::ConfigView(const BRect &frame, uint32 resize, uint32 flags)
|
|
||||||
: BView(frame, B_TRANSLATE("HPGSTranslator Settings"), resize, flags)
|
|
||||||
{
|
|
||||||
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
|
||||||
|
|
||||||
font_height fontHeight;
|
|
||||||
be_bold_font->GetHeight(&fontHeight);
|
|
||||||
float height = fontHeight.descent + fontHeight.ascent + fontHeight.leading;
|
|
||||||
|
|
||||||
BRect rect(10, 10, 200, 10 + height);
|
|
||||||
BStringView *stringView = new BStringView(rect, "title",
|
|
||||||
B_TRANSLATE("HPGS images"));
|
|
||||||
stringView->SetFont(be_bold_font);
|
|
||||||
stringView->ResizeToPreferred();
|
|
||||||
AddChild(stringView);
|
|
||||||
|
|
||||||
rect.OffsetBy(0, height + 10);
|
|
||||||
char version[256];
|
|
||||||
sprintf(version, B_TRANSLATE("Version %d.%d.%d, %s"),
|
|
||||||
int(B_TRANSLATION_MAJOR_VERSION(HPGS_TRANSLATOR_VERSION)),
|
|
||||||
int(B_TRANSLATION_MINOR_VERSION(HPGS_TRANSLATOR_VERSION)),
|
|
||||||
int(B_TRANSLATION_REVISION_VERSION(HPGS_TRANSLATOR_VERSION)),
|
|
||||||
__DATE__);
|
|
||||||
stringView = new BStringView(rect, "version", version);
|
|
||||||
stringView->ResizeToPreferred();
|
|
||||||
AddChild(stringView);
|
|
||||||
|
|
||||||
GetFontHeight(&fontHeight);
|
|
||||||
height = fontHeight.descent + fontHeight.ascent + fontHeight.leading;
|
|
||||||
|
|
||||||
rect.OffsetBy(0, height + 5);
|
|
||||||
stringView = new BStringView(rect, "copyright", B_UTF8_COPYRIGHT
|
|
||||||
"2007 Haiku Inc.");
|
|
||||||
stringView->ResizeToPreferred();
|
|
||||||
AddChild(stringView);
|
|
||||||
|
|
||||||
rect.OffsetBy(0, height + 10);
|
|
||||||
stringView = new BStringView(rect, "copyright2", B_TRANSLATE("Based on "
|
|
||||||
"HPGS (http://hpgs.berlios.de)"));
|
|
||||||
stringView->ResizeToPreferred();
|
|
||||||
AddChild(stringView);
|
|
||||||
|
|
||||||
rect.OffsetBy(0, height + 5);
|
|
||||||
stringView = new BStringView(rect, "copyright3", B_UTF8_COPYRIGHT
|
|
||||||
"2004-2006 ev-i Informationstechnologie GmbH");
|
|
||||||
stringView->ResizeToPreferred();
|
|
||||||
AddChild(stringView);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ConfigView::~ConfigView()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2004-2007, Axel Dörfler, [email protected]. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_VIEW_H
|
|
||||||
#define CONFIG_VIEW_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <View.h>
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigView : public BView {
|
|
||||||
public:
|
|
||||||
ConfigView(const BRect &frame, uint32 resize = B_FOLLOW_ALL,
|
|
||||||
uint32 flags = B_WILL_DRAW);
|
|
||||||
virtual ~ConfigView();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* CONFIG_VIEW_H */
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007, Jérôme Duval. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "HPGSTranslator.h"
|
|
||||||
#include "ConfigView.h"
|
|
||||||
#include "ReadHelper.h"
|
|
||||||
|
|
||||||
#include "hpgsimage.h"
|
|
||||||
|
|
||||||
#include <Catalog.h>
|
|
||||||
#include <Messenger.h>
|
|
||||||
#include <TranslatorRoster.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
|
||||||
#define B_TRANSLATION_CONTEXT "HPGSTranslator"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct my_hpgs_png_image_st {
|
|
||||||
hpgs_png_image image;
|
|
||||||
BPositionIO *target;
|
|
||||||
} my_hpgs_png_image;
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
my_pim_write(hpgs_image *_this, const char *filename)
|
|
||||||
{
|
|
||||||
BPositionIO* target = ((my_hpgs_png_image *)_this)->target;
|
|
||||||
unsigned char *row;
|
|
||||||
int stride, depth;
|
|
||||||
_this->vtable->get_data(_this, &row, &stride, &depth);
|
|
||||||
for (int i = 0; i< _this->height; ++i) {
|
|
||||||
ssize_t bytesWritten = target->Write(row, stride);
|
|
||||||
if (bytesWritten < B_OK)
|
|
||||||
return bytesWritten;
|
|
||||||
row += stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The input formats that this translator supports.
|
|
||||||
static const translation_format sInputFormats[] = {
|
|
||||||
{
|
|
||||||
HPGS_IMAGE_FORMAT,
|
|
||||||
B_TRANSLATOR_BITMAP,
|
|
||||||
HPGS_IN_QUALITY,
|
|
||||||
HPGS_IN_CAPABILITY,
|
|
||||||
"vector/x-hpgl2",
|
|
||||||
"HP-GL/2"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// The output formats that this translator supports.
|
|
||||||
static const translation_format sOutputFormats[] = {
|
|
||||||
{
|
|
||||||
B_TRANSLATOR_BITMAP,
|
|
||||||
B_TRANSLATOR_BITMAP,
|
|
||||||
BITS_OUT_QUALITY,
|
|
||||||
BITS_OUT_CAPABILITY,
|
|
||||||
"image/x-be-bitmap",
|
|
||||||
"Be Bitmap Format (HPGSTranslator)"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Default settings for the Translator
|
|
||||||
static const TranSetting sDefaultSettings[] = {
|
|
||||||
{B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false},
|
|
||||||
{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false}
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format);
|
|
||||||
const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format);
|
|
||||||
const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting);
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
HPGSTranslator::HPGSTranslator()
|
|
||||||
: BaseTranslator(B_TRANSLATE("HPGS images"),
|
|
||||||
B_TRANSLATE("HPGS image translator"),
|
|
||||||
HPGS_TRANSLATOR_VERSION,
|
|
||||||
sInputFormats, kNumInputFormats,
|
|
||||||
sOutputFormats, kNumOutputFormats,
|
|
||||||
"HPGSTranslator_Settings",
|
|
||||||
sDefaultSettings, kNumDefaultSettings,
|
|
||||||
B_TRANSLATOR_BITMAP, HPGS_IMAGE_FORMAT)
|
|
||||||
{
|
|
||||||
hpgs_init("/usr/local");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HPGSTranslator::~HPGSTranslator()
|
|
||||||
{
|
|
||||||
hpgs_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
HPGSTranslator::DerivedIdentify(BPositionIO *stream,
|
|
||||||
const translation_format *format, BMessage *settings,
|
|
||||||
translator_info *info, uint32 outType)
|
|
||||||
{
|
|
||||||
if (!outType)
|
|
||||||
outType = B_TRANSLATOR_BITMAP;
|
|
||||||
if (outType != B_TRANSLATOR_BITMAP)
|
|
||||||
return B_NO_TRANSLATOR;
|
|
||||||
|
|
||||||
hpgs_istream *istream = hpgs_new_wrapper_istream(stream);
|
|
||||||
|
|
||||||
status_t err = B_OK;
|
|
||||||
int verbosity = 1;
|
|
||||||
hpgs_bool multipage = HPGS_FALSE;
|
|
||||||
hpgs_bool ignore_ps = HPGS_FALSE;
|
|
||||||
hpgs_bool do_linewidth = HPGS_TRUE;
|
|
||||||
hpgs_device *size_dev = (hpgs_device *)hpgs_new_plotsize_device(ignore_ps,
|
|
||||||
do_linewidth);
|
|
||||||
hpgs_reader *reader = hpgs_new_reader(istream, size_dev, multipage,
|
|
||||||
verbosity);
|
|
||||||
if (hpgs_read(reader, HPGS_FALSE) == B_OK) {
|
|
||||||
info->type = HPGS_IMAGE_FORMAT;
|
|
||||||
info->group = B_TRANSLATOR_BITMAP;
|
|
||||||
info->quality = HPGS_IN_QUALITY;
|
|
||||||
info->capability = HPGS_IN_CAPABILITY;
|
|
||||||
snprintf(info->name, sizeof(info->name), B_TRANSLATE("HPGS image"));
|
|
||||||
strcpy(info->MIME, "vector/x-hpgl2");
|
|
||||||
} else
|
|
||||||
err = B_NO_TRANSLATOR;
|
|
||||||
|
|
||||||
free(reader);
|
|
||||||
free(size_dev);
|
|
||||||
hpgs_free_wrapper_istream(istream);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
HPGSTranslator::DerivedTranslate(BPositionIO* source,
|
|
||||||
const translator_info* info, BMessage* settings,
|
|
||||||
uint32 outType, BPositionIO* target, int32 baseType)
|
|
||||||
{
|
|
||||||
if (!outType)
|
|
||||||
outType = B_TRANSLATOR_BITMAP;
|
|
||||||
if (outType != B_TRANSLATOR_BITMAP || baseType != 0)
|
|
||||||
return B_NO_TRANSLATOR;
|
|
||||||
|
|
||||||
status_t err = B_OK;
|
|
||||||
hpgs_istream *istream = hpgs_new_wrapper_istream(source);
|
|
||||||
|
|
||||||
TranslatorBitmap header;
|
|
||||||
ssize_t bytesWritten;
|
|
||||||
uint32 dataSize;
|
|
||||||
|
|
||||||
double paper_angle = 180.0;
|
|
||||||
double paper_border = 0.0;
|
|
||||||
double paper_width = 0.0;
|
|
||||||
double paper_height = 0.0;
|
|
||||||
int verbosity = 0;
|
|
||||||
int depth = 32;
|
|
||||||
int palette = 0;
|
|
||||||
hpgs_bool multipage = HPGS_FALSE;
|
|
||||||
hpgs_bool ignore_ps = HPGS_FALSE;
|
|
||||||
hpgs_bool do_linewidth = HPGS_TRUE;
|
|
||||||
hpgs_bool do_rop3 = HPGS_TRUE;
|
|
||||||
hpgs_bool antialias = HPGS_FALSE;
|
|
||||||
int image_interpolation = 0;
|
|
||||||
double thin_alpha = 0.25;
|
|
||||||
hpgs_device *size_dev = 0;
|
|
||||||
hpgs_bbox bbox = { 0.0, 0.0, 0.0, 0.0 };
|
|
||||||
hpgs_image *image;
|
|
||||||
hpgs_paint_device *pdv;
|
|
||||||
hpgs_device *plot_dev;
|
|
||||||
|
|
||||||
size_dev = (hpgs_device *)hpgs_new_plotsize_device(ignore_ps, do_linewidth);
|
|
||||||
hpgs_reader *reader = hpgs_new_reader(istream, size_dev, multipage, verbosity);
|
|
||||||
if (hpgs_read(reader, HPGS_FALSE)) {
|
|
||||||
fprintf(stderr, B_TRANSLATE("no hpgs\n"));
|
|
||||||
err = B_NO_TRANSLATOR;
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpgs_getplotsize(size_dev,1,&bbox)<0) {
|
|
||||||
fprintf(stderr, B_TRANSLATE("no hpgs\n"));
|
|
||||||
err = B_NO_TRANSLATOR;
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the appropriate page placement.
|
|
||||||
if (paper_width > 0.0 && paper_height > 0.0) {
|
|
||||||
hpgs_reader_set_fixed_page(reader,&bbox,
|
|
||||||
paper_width, paper_height, paper_border, paper_angle);
|
|
||||||
} else {
|
|
||||||
paper_width = 200.0 * 72.0;
|
|
||||||
paper_height = 200.0 * 72.0;
|
|
||||||
hpgs_reader_set_dynamic_page(reader,&bbox,
|
|
||||||
paper_width, paper_height, paper_border, paper_angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
image = (hpgs_image*)hpgs_new_png_image((int)bbox.urx, (int)bbox.ury, depth, palette, do_rop3);
|
|
||||||
image->vtable->write = &my_pim_write;
|
|
||||||
image = (hpgs_image *)realloc(image, sizeof(my_hpgs_png_image));
|
|
||||||
((my_hpgs_png_image *)image)->target = target;
|
|
||||||
|
|
||||||
pdv = hpgs_new_paint_device(image, NULL, &bbox, antialias);
|
|
||||||
hpgs_paint_device_set_image_interpolation(pdv, image_interpolation);
|
|
||||||
hpgs_paint_device_set_thin_alpha(pdv, thin_alpha);
|
|
||||||
|
|
||||||
plot_dev = (hpgs_device *)pdv;
|
|
||||||
if (hpgs_reader_imbue(reader, plot_dev)) {
|
|
||||||
fprintf(stderr, hpgs_i18n(B_TRANSLATE("Error: Cannot imbue plot "
|
|
||||||
"device to reader: %s\n")), hpgs_get_error());
|
|
||||||
err = B_NO_TRANSLATOR;
|
|
||||||
goto err2;
|
|
||||||
}
|
|
||||||
|
|
||||||
dataSize = (int)bbox.urx * 4 * (int)bbox.ury;
|
|
||||||
|
|
||||||
header.magic = B_TRANSLATOR_BITMAP;
|
|
||||||
header.bounds.Set(0, 0, (int)bbox.urx - 1, bbox.ury - 1);
|
|
||||||
header.rowBytes = (int)bbox.urx * 4;
|
|
||||||
header.colors = B_RGBA32;
|
|
||||||
header.dataSize = dataSize;
|
|
||||||
|
|
||||||
// write out Be's Bitmap header
|
|
||||||
swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap),
|
|
||||||
B_SWAP_HOST_TO_BENDIAN);
|
|
||||||
bytesWritten = target->Write(&header, sizeof(TranslatorBitmap));
|
|
||||||
if (bytesWritten < B_OK) {
|
|
||||||
fprintf(stderr, B_TRANSLATE("Write error %s\n"),
|
|
||||||
strerror(bytesWritten));
|
|
||||||
err = bytesWritten;
|
|
||||||
goto err2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)bytesWritten != sizeof(TranslatorBitmap)) {
|
|
||||||
fprintf(stderr, "TranslatorBitmap\n");
|
|
||||||
err = B_IO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == B_OK && hpgs_read(reader, HPGS_FALSE)) {
|
|
||||||
fprintf(stderr, hpgs_i18n(B_TRANSLATE("Error: Cannot process plot "
|
|
||||||
"data %s\n")), hpgs_get_error());
|
|
||||||
err = B_NO_TRANSLATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
err2:
|
|
||||||
free(pdv);
|
|
||||||
free(image);
|
|
||||||
|
|
||||||
err1:
|
|
||||||
free(reader);
|
|
||||||
free(size_dev);
|
|
||||||
free(istream->stream);
|
|
||||||
free(istream);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BView *
|
|
||||||
HPGSTranslator::NewConfigView(TranslatorSettings *settings)
|
|
||||||
{
|
|
||||||
return new ConfigView(BRect(0, 0, 225, 175));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
BTranslator *
|
|
||||||
make_nth_translator(int32 n, image_id you, uint32 flags, ...)
|
|
||||||
{
|
|
||||||
if (n != 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return new HPGSTranslator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007, Jérôme Duval. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef HPGS_TRANSLATOR_H
|
|
||||||
#define HPGS_TRANSLATOR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "BaseTranslator.h"
|
|
||||||
|
|
||||||
#include <Translator.h>
|
|
||||||
#include <TranslatorFormats.h>
|
|
||||||
#include <TranslationDefs.h>
|
|
||||||
#include <GraphicsDefs.h>
|
|
||||||
#include <InterfaceDefs.h>
|
|
||||||
#include <DataIO.h>
|
|
||||||
#include <File.h>
|
|
||||||
#include <ByteOrder.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define HPGS_TRANSLATOR_VERSION B_TRANSLATION_MAKE_VERSION(0, 1, 0)
|
|
||||||
#define HPGS_IMAGE_FORMAT 'HPGI'
|
|
||||||
|
|
||||||
#define HPGS_IN_QUALITY 0.90
|
|
||||||
#define HPGS_IN_CAPABILITY 0.90
|
|
||||||
#define BITS_IN_QUALITY 1
|
|
||||||
#define BITS_IN_CAPABILITY 1
|
|
||||||
|
|
||||||
#define HPGS_OUT_QUALITY 0.8
|
|
||||||
#define HPGS_OUT_CAPABILITY 0.8
|
|
||||||
#define BITS_OUT_QUALITY 1
|
|
||||||
#define BITS_OUT_CAPABILITY 0.9
|
|
||||||
|
|
||||||
|
|
||||||
class HPGSTranslator : public BaseTranslator {
|
|
||||||
public:
|
|
||||||
HPGSTranslator();
|
|
||||||
virtual ~HPGSTranslator();
|
|
||||||
|
|
||||||
virtual status_t DerivedIdentify(BPositionIO *inSource,
|
|
||||||
const translation_format *inFormat, BMessage *ioExtension,
|
|
||||||
translator_info *outInfo, uint32 outType);
|
|
||||||
|
|
||||||
virtual status_t DerivedTranslate(BPositionIO *inSource,
|
|
||||||
const translator_info *inInfo, BMessage *ioExtension,
|
|
||||||
uint32 outType, BPositionIO *outDestination, int32 baseType);
|
|
||||||
|
|
||||||
virtual BView *NewConfigView(TranslatorSettings *settings);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HPGS_TRANSLATOR_H
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
SubDir HAIKU_TOP src add-ons translators hpgs ;
|
|
||||||
|
|
||||||
SubDirSysHdrs [ FDirName $(SUBDIR) lib ] ;
|
|
||||||
SubDirCcFlags -DHPGS_SHARED -std=c99 ;
|
|
||||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ;
|
|
||||||
|
|
||||||
local sources =
|
|
||||||
hpgsbase.c
|
|
||||||
hpgsbbox.c
|
|
||||||
hpgsbezier.c
|
|
||||||
hpgs.c
|
|
||||||
hpgscharacter.c
|
|
||||||
hpgsdevices.c
|
|
||||||
hpgsfont.c
|
|
||||||
hpgsglobal.c
|
|
||||||
hpgsgstate.c
|
|
||||||
hpgsi18n.c
|
|
||||||
hpgsimage.c
|
|
||||||
hpgsimagerop.c
|
|
||||||
hpgsistream.c
|
|
||||||
hpgslabel.c
|
|
||||||
hpgslexer.c
|
|
||||||
hpgsmatrix.c
|
|
||||||
hpgsostream.c
|
|
||||||
hpgspaint.c
|
|
||||||
hpgspaintimage.c
|
|
||||||
hpgspaintpath.c
|
|
||||||
hpgspath.c
|
|
||||||
hpgspcl.c
|
|
||||||
hpgspe.c
|
|
||||||
hpgspen.c
|
|
||||||
hpgspjl.c
|
|
||||||
hpgsreader.c
|
|
||||||
hpgsrop.c
|
|
||||||
hpgsscanline.c
|
|
||||||
hpgssetup.c
|
|
||||||
hpgstransform.c
|
|
||||||
hpgszostream.c
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
local architectureObject ;
|
|
||||||
for architectureObject in [ MultiArchSubDirSetup ] {
|
|
||||||
on $(architectureObject) {
|
|
||||||
UseLibraryHeaders iconv ;
|
|
||||||
UseBuildFeatureHeaders libpng ;
|
|
||||||
UseBuildFeatureHeaders zlib ;
|
|
||||||
|
|
||||||
Includes [ FGristFiles hpgsimage.c ]
|
|
||||||
: [ BuildFeatureAttribute libpng : headers ] ;
|
|
||||||
Includes [ FGristFiles hpgszostream.c ]
|
|
||||||
: [ BuildFeatureAttribute zlib : headers ] ;
|
|
||||||
|
|
||||||
Translator [ MultiArchDefaultGristFiles HPGSTranslator ] :
|
|
||||||
# HPGSTranslator classes
|
|
||||||
ConfigView.cpp
|
|
||||||
HPGSTranslator.cpp
|
|
||||||
$(sources)
|
|
||||||
: be translation libtextencoding.so
|
|
||||||
[ BuildFeatureAttribute libpng : library ]
|
|
||||||
[ BuildFeatureAttribute zlib : library ]
|
|
||||||
[ MultiArchDefaultGristFiles libtranslatorsutils.a ]
|
|
||||||
[ TargetLibsupc++ ] localestub
|
|
||||||
: true
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DoCatalogs HPGSTranslator :
|
|
||||||
x-vnd.Haiku-HPGSTranslator
|
|
||||||
:
|
|
||||||
ConfigView.cpp
|
|
||||||
HPGSTranslator.cpp
|
|
||||||
;
|
|
||||||
|
|
||||||
SEARCH on [ FGristFiles $(sources) ] = [ FDirName $(SUBDIR) lib ] ;
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007, Jérôme Duval. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef READ_HELPER_H
|
|
||||||
#define READ_HELPER_H
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <hpgs.h>
|
|
||||||
#include <DataIO.h>
|
|
||||||
|
|
||||||
#include "StreamBuffer.h"
|
|
||||||
|
|
||||||
typedef struct my_hpgs_istream_st
|
|
||||||
{
|
|
||||||
StreamBuffer *buffer;
|
|
||||||
status_t iseof;
|
|
||||||
} my_hpgs_istream;
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_getc(my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
unsigned char value;
|
|
||||||
status_t error;
|
|
||||||
stream->iseof = 0;
|
|
||||||
error = stream->buffer->Read((void *)&value, sizeof(unsigned char));
|
|
||||||
if (error > B_OK)
|
|
||||||
return value;
|
|
||||||
stream->iseof = EOF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_ungetc(int c, my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
return stream->buffer->Seek(-1, SEEK_CUR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_close(my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_eof(my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
return stream->iseof;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_error(my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_tell(my_hpgs_istream *stream, size_t *pos)
|
|
||||||
{
|
|
||||||
*pos = stream->buffer->Position();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_seek(my_hpgs_istream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
stream->buffer->Seek(pos, SEEK_SET);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
positionio_seekend(my_hpgs_istream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
stream->buffer->Seek(pos, SEEK_END);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
positionio_read(void *ptr, size_t size, size_t nmemb, my_hpgs_istream *stream)
|
|
||||||
{
|
|
||||||
unsigned char *iptr = (unsigned char *)ptr;
|
|
||||||
size_t i = 0;
|
|
||||||
for (; i < nmemb; i++) {
|
|
||||||
if (size != (size_t)stream->buffer->Read(iptr, size))
|
|
||||||
break;
|
|
||||||
iptr += size;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static hpgs_istream_vtable positionio_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_istream_getc_func_t) positionio_getc,
|
|
||||||
(hpgs_istream_ungetc_func_t) positionio_ungetc,
|
|
||||||
(hpgs_istream_close_func_t) positionio_close,
|
|
||||||
(hpgs_istream_iseof_func_t) positionio_eof,
|
|
||||||
(hpgs_istream_iserror_func_t) positionio_error,
|
|
||||||
(hpgs_istream_seek_func_t) positionio_seek,
|
|
||||||
(hpgs_istream_tell_func_t) positionio_tell,
|
|
||||||
(hpgs_istream_read_func_t) positionio_read,
|
|
||||||
(hpgs_istream_seekend_func_t) positionio_seekend
|
|
||||||
};
|
|
||||||
|
|
||||||
hpgs_istream *
|
|
||||||
hpgs_new_wrapper_istream(BPositionIO *stream)
|
|
||||||
{
|
|
||||||
hpgs_istream *ret = (hpgs_istream *)malloc(sizeof(hpgs_istream));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret->stream = (my_hpgs_istream *)malloc(sizeof(my_hpgs_istream));
|
|
||||||
ret->vtable = &positionio_vtable;
|
|
||||||
((my_hpgs_istream *)ret->stream)->iseof = 0;
|
|
||||||
((my_hpgs_istream *)ret->stream)->buffer = new StreamBuffer(stream, 2048);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
hpgs_free_wrapper_istream(hpgs_istream *istream)
|
|
||||||
{
|
|
||||||
delete ((my_hpgs_istream *)istream->stream)->buffer;
|
|
||||||
free(istream->stream);
|
|
||||||
free(istream);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // READ_HELPER_H
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,176 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsbase.c 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of basic helper functions. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
#include<string.h>
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Parses a physical paper size with a given unit and returns the
|
|
||||||
width and the height of the paper in PostScript pt (1/72 inch).
|
|
||||||
|
|
||||||
The standard formats A4,A3,A2,A1 an A0 as well
|
|
||||||
as their landscape counterparts A4l,A3l,A2l,A1l and A0l are
|
|
||||||
accepted.
|
|
||||||
|
|
||||||
If the string does not represent a standard paper size,
|
|
||||||
it must be of the format <width>x<height>, where <width>
|
|
||||||
and <height> must follow the convention of \c hpgs_parse_papersize.
|
|
||||||
|
|
||||||
The function returns 0, if the string matches these conventions or
|
|
||||||
-1, if the string is in a wrong format.
|
|
||||||
*/
|
|
||||||
int hpgs_parse_papersize(const char *str, double *pt_width, double *pt_height)
|
|
||||||
{
|
|
||||||
if (strcmp(str,"A4")==0)
|
|
||||||
{
|
|
||||||
*pt_width = 595.91084545538825881889;
|
|
||||||
*pt_height = 842.74519960822752756850;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A3")==0)
|
|
||||||
{
|
|
||||||
*pt_width = 842.74519960822752756850;
|
|
||||||
*pt_height = 1191.82169091077651766614;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A2")==0)
|
|
||||||
{
|
|
||||||
*pt_width = 1191.82169091077651766614;
|
|
||||||
*pt_height = 1685.49039921645505516535;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A1")==0)
|
|
||||||
{
|
|
||||||
*pt_width = 1685.49039921645505516535;
|
|
||||||
*pt_height = 2383.64338182155303536062;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A0")==0)
|
|
||||||
{
|
|
||||||
*pt_width = 2383.64338182155303536062;
|
|
||||||
*pt_height = 3370.98079843291011035905;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A4l")==0)
|
|
||||||
{
|
|
||||||
*pt_height = 595.91084545538825881889;
|
|
||||||
*pt_width = 842.74519960822752756850;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A3l")==0)
|
|
||||||
{
|
|
||||||
*pt_height = 842.74519960822752756850;
|
|
||||||
*pt_width = 1191.82169091077651766614;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A2l")==0)
|
|
||||||
{
|
|
||||||
*pt_height = 1191.82169091077651766614;
|
|
||||||
*pt_width = 1685.49039921645505516535;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A1l")==0)
|
|
||||||
{
|
|
||||||
*pt_height = 1685.49039921645505516535;
|
|
||||||
*pt_width = 2383.64338182155303536062;
|
|
||||||
}
|
|
||||||
else if (strcmp(str,"A0l")==0)
|
|
||||||
{
|
|
||||||
*pt_height = 2383.64338182155303536062;
|
|
||||||
*pt_width = 3370.98079843291011035905;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// find the 'x'
|
|
||||||
const char *x=strchr(str,'x');
|
|
||||||
char wstr[32];
|
|
||||||
int l;
|
|
||||||
|
|
||||||
if (!x) return -1;
|
|
||||||
l=x-str;
|
|
||||||
if (l > 31) return -1;
|
|
||||||
|
|
||||||
strncpy(wstr,str,l);
|
|
||||||
wstr[l] = '\0';
|
|
||||||
|
|
||||||
if (hpgs_parse_length(wstr,pt_width)) return -1;
|
|
||||||
if (hpgs_parse_length(str+l+1,pt_height)) return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Parses a physical length with a given unit and returns the length
|
|
||||||
in PostScript pt (1/72 inch).
|
|
||||||
|
|
||||||
The following formats are accepted:
|
|
||||||
|
|
||||||
\verbatim
|
|
||||||
27
|
|
||||||
37pt
|
|
||||||
4.5inch
|
|
||||||
0.37m
|
|
||||||
1.5cm
|
|
||||||
11.34mm
|
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
If no unit is specified, PostScript points (1/72 inch) are assumed.
|
|
||||||
|
|
||||||
The function returns 0, if the string matches these conventions or
|
|
||||||
-1, if the string is in a wrong format.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int hpgs_parse_length(const char *str, double *pt_length)
|
|
||||||
{
|
|
||||||
const char *unit="pt";
|
|
||||||
|
|
||||||
char * endptr = (char*)str;
|
|
||||||
|
|
||||||
*pt_length = strtod(str,&endptr);
|
|
||||||
|
|
||||||
if (endptr == str) return -1;
|
|
||||||
if (*endptr) unit = endptr;
|
|
||||||
|
|
||||||
if (strcmp(unit,"cm")==0)
|
|
||||||
{
|
|
||||||
*pt_length *= 72.0 / 2.54;
|
|
||||||
}
|
|
||||||
else if (strcmp(unit,"mm")==0)
|
|
||||||
{
|
|
||||||
*pt_length *= 72.0 / 25.4;
|
|
||||||
}
|
|
||||||
else if (strcmp(unit,"m")==0)
|
|
||||||
{
|
|
||||||
*pt_length *= 72.0 / 0.0254;
|
|
||||||
}
|
|
||||||
else if (strcmp(unit,"inch")==0)
|
|
||||||
{
|
|
||||||
*pt_length *= 72.0;
|
|
||||||
}
|
|
||||||
else if (strcmp(unit,"pt"))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsbbox.c 298 2006-03-05 18:18:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the public API for bounding boxes. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns, whether the two bounding boxes are equal.
|
|
||||||
*/
|
|
||||||
hpgs_bool hpgs_bbox_isequal (const hpgs_bbox *bb1, const hpgs_bbox *bb2)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
bb1->llx == bb2->llx &&
|
|
||||||
bb1->lly == bb2->lly &&
|
|
||||||
bb1->urx == bb2->urx &&
|
|
||||||
bb1->ury == bb2->ury;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Calculates the distance of the two bounding boxes.
|
|
||||||
*/
|
|
||||||
void hpgs_bbox_distance (hpgs_point *d, const hpgs_bbox *bb1, const hpgs_bbox *bb2)
|
|
||||||
{
|
|
||||||
if (hpgs_bbox_isnull(bb1) ||
|
|
||||||
hpgs_bbox_isnull(bb2) )
|
|
||||||
{
|
|
||||||
d->x = 0.0;
|
|
||||||
d->y = 0.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bb2->llx >= bb1->urx)
|
|
||||||
{
|
|
||||||
d->x = bb2->llx - bb1->urx;
|
|
||||||
}
|
|
||||||
else if (bb1->llx >= bb2->urx)
|
|
||||||
{
|
|
||||||
d->x = bb1->llx - bb2->urx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d->x = 0.0;
|
|
||||||
|
|
||||||
if (bb2->lly >= bb1->ury)
|
|
||||||
{
|
|
||||||
d->y = bb2->lly - bb1->ury;
|
|
||||||
}
|
|
||||||
else if (bb1->lly >= bb2->ury)
|
|
||||||
{
|
|
||||||
d->y = bb1->lly - bb2->ury;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d->y = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns, whether the bounding box is null.
|
|
||||||
A null bounding box is als empty.
|
|
||||||
An empty bounding box may not be null, if
|
|
||||||
either of the x or y extend of the bounding box
|
|
||||||
is exactly zero.
|
|
||||||
*/
|
|
||||||
hpgs_bool hpgs_bbox_isnull (const hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
bb->llx > bb->urx ||
|
|
||||||
bb->lly > bb->ury;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns, whether the bounding box is empty.
|
|
||||||
*/
|
|
||||||
hpgs_bool hpgs_bbox_isempty (const hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
bb->llx >= bb->urx ||
|
|
||||||
bb->lly >= bb->ury;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets this bounding box to an empty bounding box.
|
|
||||||
*/
|
|
||||||
void hpgs_bbox_null (hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
bb->llx = 1.0e20;
|
|
||||||
bb->lly = 1.0e20;
|
|
||||||
bb->urx = -1.0e20;
|
|
||||||
bb->ury = -1.0e20;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Expands \c bb1 in order to comprise the smallest bounding box
|
|
||||||
containing both \c bb1 and \c bb2
|
|
||||||
*/
|
|
||||||
void hpgs_bbox_expand (hpgs_bbox *bb1, const hpgs_bbox *bb2)
|
|
||||||
{
|
|
||||||
if (bb2->llx < bb1->llx) bb1->llx = bb2->llx;
|
|
||||||
if (bb2->lly < bb1->lly) bb1->lly = bb2->lly;
|
|
||||||
if (bb2->urx > bb1->urx) bb1->urx = bb2->urx;
|
|
||||||
if (bb2->ury > bb1->ury) bb1->ury = bb2->ury;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Shrinks \c bb1 in order to comprise the intersection
|
|
||||||
of \c bb1 and \c bb2. If the bounding boxes do not intersect,
|
|
||||||
\c bb1 is set to a null bounding box.
|
|
||||||
*/
|
|
||||||
void hpgs_bbox_intersect (hpgs_bbox *bb1, const hpgs_bbox *bb2)
|
|
||||||
{
|
|
||||||
if (bb2->llx > bb1->llx) bb1->llx=bb2->llx;
|
|
||||||
if (bb2->lly > bb1->lly) bb1->lly=bb2->lly;
|
|
||||||
if (bb2->urx < bb1->urx) bb1->urx=bb2->urx;
|
|
||||||
if (bb2->ury < bb1->ury) bb1->ury=bb2->ury;
|
|
||||||
}
|
|
||||||
@@ -1,580 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsbezier.c 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Bezier spline length and scanline cut implementation. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgspaint.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// #define HPGS_BEZIER_DEBUG
|
|
||||||
|
|
||||||
/*! Calculates the derivation of the bezier curve starting
|
|
||||||
at point \c i of \c path at curve parameter \c t.
|
|
||||||
*/
|
|
||||||
void hpgs_bezier_path_delta(const hpgs_paint_path *path, int i,
|
|
||||||
double t, hpgs_point *p)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
p->x = 3.0* ((path->points[i+1].p.x-path->points[i].p.x)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.x-path->points[i+1].p.x) * tm*tp+
|
|
||||||
(path->points[i+3].p.x-path->points[i+2].p.x) * tp*tp);
|
|
||||||
|
|
||||||
p->y = 3.0 * ((path->points[i+1].p.y-path->points[i].p.y)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.y-path->points[i+1].p.y) * tm*tp+
|
|
||||||
(path->points[i+3].p.y-path->points[i+2].p.y) * tp*tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the derivation of the bezier curve starting
|
|
||||||
at point \c i of \c path at curve parameter \c t.
|
|
||||||
*/
|
|
||||||
double hpgs_bezier_path_delta_x(const hpgs_paint_path *path, int i, double t)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
return 3.0* ((path->points[i+1].p.x-path->points[i].p.x)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.x-path->points[i+1].p.x) * tm*tp+
|
|
||||||
(path->points[i+3].p.x-path->points[i+2].p.x) * tp*tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the derivation of the bezier curve starting
|
|
||||||
at point \c i of \c path at curve parameter \c t.
|
|
||||||
*/
|
|
||||||
double hpgs_bezier_path_delta_y(const hpgs_paint_path *path, int i, double t)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
return 3.0* ((path->points[i+1].p.y-path->points[i].p.y)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.y-path->points[i+1].p.y) * tm*tp+
|
|
||||||
(path->points[i+3].p.y-path->points[i+2].p.y) * tp*tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the tangent to the bezier curve starting
|
|
||||||
at point \c i of \c path at curve parameter \c t.
|
|
||||||
|
|
||||||
If \c orientation is \c 1, the tangent is calculated with increasing
|
|
||||||
curve parameter, if we meet a singularity (right tangent).
|
|
||||||
|
|
||||||
If \c orientation is \c -1, the tangent is calculated with decreasing
|
|
||||||
curve parameter, if we meet a singularity (left tangent).
|
|
||||||
|
|
||||||
If \c orientation is \c 0, the tangent is calculated with decreased
|
|
||||||
and increased curve parameter, if we meet a singularity (mid tangent).
|
|
||||||
*/
|
|
||||||
|
|
||||||
void hpgs_bezier_path_tangent(const hpgs_paint_path *path, int i,
|
|
||||||
double t, int orientation,
|
|
||||||
double ytol, hpgs_point *p)
|
|
||||||
{
|
|
||||||
hpgs_bezier_path_delta(path,i,t,p);
|
|
||||||
|
|
||||||
double l = hypot(p->x,p->y);
|
|
||||||
|
|
||||||
if (l < ytol)
|
|
||||||
{
|
|
||||||
hpgs_point p1;
|
|
||||||
|
|
||||||
if (orientation <= 0)
|
|
||||||
hpgs_bezier_path_point(path,i,t-1.0e-4,&p1);
|
|
||||||
else
|
|
||||||
hpgs_bezier_path_point(path,i,t,&p1);
|
|
||||||
|
|
||||||
if (orientation >= 0)
|
|
||||||
hpgs_bezier_path_point(path,i,t+1.0e-4,p);
|
|
||||||
else
|
|
||||||
hpgs_bezier_path_point(path,i,t,p);
|
|
||||||
|
|
||||||
p->x -= p1.x;
|
|
||||||
p->y -= p1.y;
|
|
||||||
|
|
||||||
l = hypot(p->x,p->y);
|
|
||||||
if (l < ytol*1.0e-4) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->x /= l;
|
|
||||||
p->y /= l;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int quad_roots (double a, double b, double c,
|
|
||||||
double t0, double t1, double *t)
|
|
||||||
{
|
|
||||||
if (fabs(a) < (fabs(b)>fabs(c) ? fabs(b) : fabs(c)) * 1.0e-8 || fabs(a) < 1.0e-16)
|
|
||||||
{
|
|
||||||
if (fabs(b) < fabs(c) * 1.0e-8)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
t[0] = -c/b;
|
|
||||||
return t[0] > t0 && t[0] < t1;
|
|
||||||
}
|
|
||||||
|
|
||||||
double p = b/a;
|
|
||||||
double q = c/a;
|
|
||||||
|
|
||||||
double det = 0.25*p-q;
|
|
||||||
|
|
||||||
if (det < 0) return 0;
|
|
||||||
|
|
||||||
det = sqrt(det);
|
|
||||||
|
|
||||||
if (p > 0.0)
|
|
||||||
t[0] = -0.5*p - det;
|
|
||||||
else
|
|
||||||
t[0] = -0.5*p + det;
|
|
||||||
|
|
||||||
if (fabs(t[0]) < 1.0e-8)
|
|
||||||
return t[0] > t0 && t[0] < t1;
|
|
||||||
|
|
||||||
t[1] = q / t[0];
|
|
||||||
|
|
||||||
if (t[0] <= t0 || t[0] >= t1)
|
|
||||||
{
|
|
||||||
t[0] = t[1];
|
|
||||||
return t[0] > t0 && t[0] < t1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t[1] <= t0 || t[1] >= t1)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (t[0] > t[1])
|
|
||||||
{
|
|
||||||
double tmp = t[1];
|
|
||||||
t[1] = t[0];
|
|
||||||
t[0] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fabs(t[0]-t[1]) < 1.0e-8 ? 1 : 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Calculates the singularities of the bezier curve in the
|
|
||||||
parameter interval from \c t0 to \c t1.
|
|
||||||
|
|
||||||
We calculate points, where the cross product of the first derivative
|
|
||||||
and the second derivative vanishes. These points include points, where
|
|
||||||
the first or second derivative vanishes. Additionally, turning points
|
|
||||||
of the curve are also included.
|
|
||||||
|
|
||||||
\c tx is a pointer to an array of at least two double values,
|
|
||||||
in which the position of the singularities is returned.
|
|
||||||
*/
|
|
||||||
void hpgs_bezier_path_singularities(const hpgs_paint_path *path, int i,
|
|
||||||
double t0, double t1,
|
|
||||||
int *nx, double *tx)
|
|
||||||
{
|
|
||||||
// The second order spline p'(t) cross p''(t)
|
|
||||||
double k0 =
|
|
||||||
(path->points[i+1].p.x-path->points[i].p.x)*(path->points[i+2].p.y-path->points[i+1].p.y) -
|
|
||||||
(path->points[i+1].p.y-path->points[i].p.y)*(path->points[i+2].p.x-path->points[i+1].p.x);
|
|
||||||
|
|
||||||
double k1 =
|
|
||||||
(path->points[i+1].p.x-path->points[i].p.x)*(path->points[i+3].p.y-path->points[i+2].p.y) -
|
|
||||||
(path->points[i+1].p.y-path->points[i].p.y)*(path->points[i+3].p.x-path->points[i+2].p.x);
|
|
||||||
|
|
||||||
double k2 =
|
|
||||||
(path->points[i+2].p.x-path->points[i+1].p.x)*(path->points[i+3].p.y-path->points[i+2].p.y) -
|
|
||||||
(path->points[i+2].p.y-path->points[i+1].p.y)*(path->points[i+3].p.x-path->points[i+2].p.x);
|
|
||||||
|
|
||||||
|
|
||||||
// coefficients for the quadratic equations.
|
|
||||||
double a = k0 - k1 + k2;
|
|
||||||
|
|
||||||
double b = k2 - k0;
|
|
||||||
|
|
||||||
double c = 0.25 * (k0 + k1 + k2);
|
|
||||||
|
|
||||||
*nx = quad_roots (a,b,c,t0,t1,tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_quad (const hpgs_point *p1,
|
|
||||||
const hpgs_point *d1,
|
|
||||||
const hpgs_point *p2,
|
|
||||||
const hpgs_point *d2,
|
|
||||||
int *nx, hpgs_point *points)
|
|
||||||
{
|
|
||||||
double det = d1->y * d2->x - d1->x * d2->y;
|
|
||||||
|
|
||||||
if (fabs(det) < 1.0e-8)
|
|
||||||
{
|
|
||||||
points[*nx].x = 0.5 * (p1->x + p2->x);
|
|
||||||
points[*nx].y = 0.5 * (p1->y + p2->y);
|
|
||||||
++*nx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double s = (d2->x*(p2->y-p1->y)-
|
|
||||||
d2->y*(p2->x-p1->x) )/det;
|
|
||||||
|
|
||||||
points[*nx].x = p1->x + s*d1->x;
|
|
||||||
points[*nx].y = p1->y + s*d1->y;
|
|
||||||
++*nx;
|
|
||||||
}
|
|
||||||
|
|
||||||
points[*nx].x = p2->x;
|
|
||||||
points[*nx].y = p2->y;
|
|
||||||
++*nx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Approximates the bezier curve segment in the
|
|
||||||
parameter interval from \c t0 to \c t1 with quadratic bezier splines.
|
|
||||||
|
|
||||||
The array \c points is used to return the quadratic bezier segments and
|
|
||||||
must have a dimension of at least 16 points.
|
|
||||||
|
|
||||||
\c nx returns the number of generated points, which is always an even
|
|
||||||
number. The first point is the control point of the first quadratic
|
|
||||||
spline, the second point the endpoint of the first quadratic spline
|
|
||||||
and so on.
|
|
||||||
*/
|
|
||||||
void hpgs_bezier_path_to_quadratic(const hpgs_paint_path *path, int i,
|
|
||||||
double t0, double t1,
|
|
||||||
int *nx, hpgs_point *points)
|
|
||||||
{
|
|
||||||
// The second order spline p'(t) cross p''(t)
|
|
||||||
double k0 =
|
|
||||||
(path->points[i+1].p.x-path->points[i].p.x)*(path->points[i+2].p.y-path->points[i+1].p.y) -
|
|
||||||
(path->points[i+1].p.y-path->points[i].p.y)*(path->points[i+2].p.x-path->points[i+1].p.x);
|
|
||||||
|
|
||||||
double k1 =
|
|
||||||
(path->points[i+1].p.x-path->points[i].p.x)*(path->points[i+3].p.y-path->points[i+2].p.y) -
|
|
||||||
(path->points[i+1].p.y-path->points[i].p.y)*(path->points[i+3].p.x-path->points[i+2].p.x);
|
|
||||||
|
|
||||||
double k2 =
|
|
||||||
(path->points[i+2].p.x-path->points[i+1].p.x)*(path->points[i+3].p.y-path->points[i+2].p.y) -
|
|
||||||
(path->points[i+2].p.y-path->points[i+1].p.y)*(path->points[i+3].p.x-path->points[i+2].p.x);
|
|
||||||
|
|
||||||
|
|
||||||
double xmax,xmin,ymin,ymax;
|
|
||||||
|
|
||||||
// coefficients for the quadratic equations.
|
|
||||||
double a = k0 - k1 + k2;
|
|
||||||
|
|
||||||
double b = k2 - k0;
|
|
||||||
|
|
||||||
double c = 0.25 * (k0 + k1 + k2);
|
|
||||||
|
|
||||||
// at most three partition points:
|
|
||||||
// extrem, roots of the curvature spline
|
|
||||||
double tpart[5];
|
|
||||||
|
|
||||||
// get the roots.
|
|
||||||
int ipart;
|
|
||||||
int npart = quad_roots (a,b,c,t0,t1,tpart+1) + 1;
|
|
||||||
|
|
||||||
// add the extreme point.
|
|
||||||
if (fabs(a) > fabs(b))
|
|
||||||
{
|
|
||||||
double text = -0.5 * b/a;
|
|
||||||
|
|
||||||
if (npart == 3)
|
|
||||||
{
|
|
||||||
tpart[3] = tpart[2];
|
|
||||||
tpart[2] = text;
|
|
||||||
npart = 3;
|
|
||||||
}
|
|
||||||
else if (text > t0 && text < t1)
|
|
||||||
{
|
|
||||||
if (npart == 2 && text < tpart[1])
|
|
||||||
{
|
|
||||||
tpart[2] = tpart[1];
|
|
||||||
tpart[1] = text;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tpart[npart] = text;
|
|
||||||
|
|
||||||
++npart;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tpart[0] = t0;
|
|
||||||
tpart[npart] = t1;
|
|
||||||
|
|
||||||
xmax = xmin = path->points[i].p.x;
|
|
||||||
if (path->points[i+1].p.x > xmax) xmax = path->points[i+1].p.x;
|
|
||||||
if (path->points[i+2].p.x > xmax) xmax = path->points[i+2].p.x;
|
|
||||||
if (path->points[i+3].p.x > xmax) xmax = path->points[i+3].p.x;
|
|
||||||
if (path->points[i+1].p.x < xmin) xmin = path->points[i+1].p.x;
|
|
||||||
if (path->points[i+2].p.x < xmin) xmin = path->points[i+2].p.x;
|
|
||||||
if (path->points[i+3].p.x < xmin) xmin = path->points[i+3].p.x;
|
|
||||||
|
|
||||||
ymax = ymin = path->points[i].p.y;
|
|
||||||
if (path->points[i+1].p.y > ymax) ymax = path->points[i+1].p.y;
|
|
||||||
if (path->points[i+2].p.y > ymax) ymax = path->points[i+2].p.y;
|
|
||||||
if (path->points[i+3].p.y > ymax) ymax = path->points[i+3].p.y;
|
|
||||||
if (path->points[i+1].p.y < ymin) ymin = path->points[i+1].p.y;
|
|
||||||
if (path->points[i+2].p.y < ymin) ymin = path->points[i+2].p.y;
|
|
||||||
if (path->points[i+3].p.y < ymin) ymin = path->points[i+3].p.y;
|
|
||||||
|
|
||||||
double curv0 =
|
|
||||||
k0*(0.5-tpart[0])*(0.5-tpart[0]) +
|
|
||||||
k1*(0.5-tpart[0])*(0.5+tpart[0]) +
|
|
||||||
k2*(0.5+tpart[0])*(0.5+tpart[0]);
|
|
||||||
|
|
||||||
*nx = 0;
|
|
||||||
|
|
||||||
for (ipart=0; ipart<npart; ++ipart)
|
|
||||||
{
|
|
||||||
double curv1 =
|
|
||||||
k0*(0.5-tpart[ipart+1])*(0.5-tpart[ipart+1]) +
|
|
||||||
k1*(0.5-tpart[ipart+1])*(0.5+tpart[ipart+1]) +
|
|
||||||
k2*(0.5+tpart[ipart+1])*(0.5+tpart[ipart+1]);
|
|
||||||
|
|
||||||
int n_splines = 1;
|
|
||||||
|
|
||||||
if (fabs(xmax-xmin)<1.0e-8 && fabs(ymax-ymin) < 1.0e-8)
|
|
||||||
n_splines = (int)(16.0 * fabs(curv0-curv1)/((xmax-xmin)*(ymax-ymin)));
|
|
||||||
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (n_splines < 1) n_splines = 1;
|
|
||||||
else if (n_splines > 8/npart) n_splines = 8/npart;
|
|
||||||
|
|
||||||
hpgs_point d1;
|
|
||||||
hpgs_point p1;
|
|
||||||
|
|
||||||
hpgs_bezier_path_point(path,i,tpart[ipart],&p1);
|
|
||||||
hpgs_bezier_path_tangent(path,i,tpart[ipart],1,1.0e-3,&d1);
|
|
||||||
|
|
||||||
for (j=1;j<=n_splines;++j)
|
|
||||||
{
|
|
||||||
double t = tpart[ipart] + (tpart[ipart+1]-tpart[ipart]) * j / (double)n_splines;
|
|
||||||
|
|
||||||
hpgs_point d2;
|
|
||||||
hpgs_point p2;
|
|
||||||
|
|
||||||
hpgs_bezier_path_point(path,i,t,&p2);
|
|
||||||
hpgs_bezier_path_tangent(path,i,t,j<n_splines ? 0 : -1,1.0e-3,&d2);
|
|
||||||
|
|
||||||
add_quad(&p1,&d1,&p2,&d2,nx,points);
|
|
||||||
|
|
||||||
p1 = p2;
|
|
||||||
d1 = d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
curv0 = curv1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Internal: Calculates the derivation of the curve length
|
|
||||||
of the bezier curve \c b at curve parameter \c t.
|
|
||||||
*/
|
|
||||||
static double bezier_dl(const hpgs_paint_path *path, int i, double t)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
return 3.0*hypot((path->points[i+1].p.x-path->points[i].p.x)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.x-path->points[i+1].p.x) * tm*tp+
|
|
||||||
(path->points[i+3].p.x-path->points[i+2].p.x) * tp*tp,
|
|
||||||
|
|
||||||
(path->points[i+1].p.y-path->points[i].p.y)*tm*tm+
|
|
||||||
2.0 * (path->points[i+2].p.y-path->points[i+1].p.y) * tm*tp+
|
|
||||||
(path->points[i+3].p.y-path->points[i+2].p.y) * tp*tp
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the curve lengths at an equidistant grid
|
|
||||||
of curve parmeters by na numerical quadrature.
|
|
||||||
|
|
||||||
You must call this subroutine before using
|
|
||||||
\c hpgs_bezier_length_param.
|
|
||||||
*/
|
|
||||||
void hpgs_bezier_length_init(hpgs_bezier_length *b,
|
|
||||||
const hpgs_paint_path *path, int i)
|
|
||||||
{
|
|
||||||
int ip;
|
|
||||||
|
|
||||||
b->dl[0] = bezier_dl(path,i,-0.5);
|
|
||||||
|
|
||||||
b->l[0] = 0.0;
|
|
||||||
|
|
||||||
for (ip=1;ip<=16;++ip)
|
|
||||||
{
|
|
||||||
double dlm0,dlm1;
|
|
||||||
|
|
||||||
// Lobatto quadrature with order 4.
|
|
||||||
b->dl[ip] = bezier_dl(path,i,(ip-8.0)*0.0625);
|
|
||||||
|
|
||||||
dlm0 = bezier_dl(path,i,(ip-(8.5+0.22360679774997896964))*0.0625);
|
|
||||||
dlm1 = bezier_dl(path,i,(ip-(8.5-0.22360679774997896964))*0.0625);
|
|
||||||
|
|
||||||
b->l[ip] = b->l[ip-1] +
|
|
||||||
(b->dl[ip-1] + 5.0 * (dlm0 + dlm1) + b->dl[ip])/(16.0*12.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Returns the curve parameter at the bezier curve \c b
|
|
||||||
corresponding to a curve length \c l.
|
|
||||||
|
|
||||||
You must have called \c hpgs_bezier_length_init before using
|
|
||||||
this function.
|
|
||||||
*/
|
|
||||||
double hpgs_bezier_length_param(const hpgs_bezier_length *b, double l)
|
|
||||||
{
|
|
||||||
// binary search.
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (l >= b->l[i+8]) i+=8;
|
|
||||||
if (l >= b->l[i+4]) i+=4;
|
|
||||||
if (l >= b->l[i+2]) i+=2;
|
|
||||||
if (l >= b->l[i+1]) ++i;
|
|
||||||
|
|
||||||
double dl = b->l[i+1]-b->l[i];
|
|
||||||
double ll = (l-b->l[i])/dl;
|
|
||||||
|
|
||||||
return
|
|
||||||
(i - 8.0 + ll*ll*(3.0-2.0*ll)) * 0.0625 +
|
|
||||||
(ll*(ll*(ll-2.0)+1.0) / b->dl[i] + ll*ll*(ll-1.0) / b->dl[i+1] ) * dl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the minimal x component of all four control points of
|
|
||||||
the bezier spline. */
|
|
||||||
double hpgs_bezier_path_xmin (const hpgs_paint_path *path, int i)
|
|
||||||
{
|
|
||||||
double x0 =
|
|
||||||
path->points[i].p.x < path->points[i+1].p.x ?
|
|
||||||
path->points[i].p.x : path->points[i+1].p.x;
|
|
||||||
|
|
||||||
double x1 =
|
|
||||||
path->points[i+2].p.x < path->points[i+3].p.x ?
|
|
||||||
path->points[i+2].p.x : path->points[i+3].p.x;
|
|
||||||
|
|
||||||
return x0 < x1 ? x0 : x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the maximal x component of all four control points of
|
|
||||||
the bezier spline. */
|
|
||||||
double hpgs_bezier_path_xmax (const hpgs_paint_path *path, int i)
|
|
||||||
{
|
|
||||||
double x0 =
|
|
||||||
path->points[i].p.x > path->points[i+1].p.x ?
|
|
||||||
path->points[i].p.x : path->points[i+1].p.x;
|
|
||||||
|
|
||||||
double x1 =
|
|
||||||
path->points[i+2].p.x > path->points[i+3].p.x ?
|
|
||||||
path->points[i+2].p.x : path->points[i+3].p.x;
|
|
||||||
|
|
||||||
return x0 > x1 ? x0 : x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the minimal y component of all four control points of
|
|
||||||
the bezier spline. */
|
|
||||||
double hpgs_bezier_path_ymin (const hpgs_paint_path *path, int i)
|
|
||||||
{
|
|
||||||
double y0 =
|
|
||||||
path->points[i].p.y < path->points[i+1].p.y ?
|
|
||||||
path->points[i].p.y : path->points[i+1].p.y;
|
|
||||||
|
|
||||||
double y1 =
|
|
||||||
path->points[i+2].p.y < path->points[i+3].p.y ?
|
|
||||||
path->points[i+2].p.y : path->points[i+3].p.y;
|
|
||||||
|
|
||||||
return y0 < y1 ? y0 : y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the maximal y component of all four control points of
|
|
||||||
the bezier spline. */
|
|
||||||
double hpgs_bezier_path_ymax (const hpgs_paint_path *path, int i)
|
|
||||||
{
|
|
||||||
double y0 =
|
|
||||||
path->points[i].p.y > path->points[i+1].p.y ?
|
|
||||||
path->points[i].p.y : path->points[i+1].p.y;
|
|
||||||
|
|
||||||
double y1 =
|
|
||||||
path->points[i+2].p.y > path->points[i+3].p.y ?
|
|
||||||
path->points[i+2].p.y : path->points[i+3].p.y;
|
|
||||||
|
|
||||||
return y0 > y1 ? y0 : y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the x component of a point on the bezier spline. */
|
|
||||||
double hpgs_bezier_path_x (const hpgs_paint_path *path, int i, double t)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
return
|
|
||||||
path->points[i].p.x *tm*tm*tm +
|
|
||||||
3.0 * tm*tp * (path->points[i+1].p.x * tm + path->points[i+2].p.x * tp) +
|
|
||||||
path->points[i+3].p.x * tp*tp*tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the y component of a point on the bezier spline. */
|
|
||||||
double hpgs_bezier_path_y (const hpgs_paint_path *path, int i, double t)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
return
|
|
||||||
path->points[i].p.y *tm*tm*tm +
|
|
||||||
3.0 * tm*tp * (path->points[i+1].p.y * tm + path->points[i+2].p.y * tp) +
|
|
||||||
path->points[i+3].p.y * tp*tp*tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Calculates the point on the bezier curve starting
|
|
||||||
at point \c i of \c path at curve parameter \c t.
|
|
||||||
*/
|
|
||||||
void hpgs_bezier_path_point(const hpgs_paint_path *path, int i,
|
|
||||||
double t, hpgs_point *p)
|
|
||||||
{
|
|
||||||
double tp,tm;
|
|
||||||
|
|
||||||
tp = t + 0.5;
|
|
||||||
tm = 0.5 - t;
|
|
||||||
|
|
||||||
p->x =
|
|
||||||
path->points[i].p.x *tm*tm*tm +
|
|
||||||
3.0 * tm*tp * (path->points[i+1].p.x * tm + path->points[i+2].p.x * tp) +
|
|
||||||
path->points[i+3].p.x * tp*tp*tp;
|
|
||||||
|
|
||||||
p->y =
|
|
||||||
path->points[i].p.y *tm*tm*tm +
|
|
||||||
3.0 * tm*tp * (path->points[i+1].p.y * tm + path->points[i+2].p.y * tp) +
|
|
||||||
path->points[i+3].p.y * tp*tp*tp;
|
|
||||||
}
|
|
||||||
@@ -1,686 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgscharacter.c 383 2007-03-18 18:29:22Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
// The size of a line feed measured in the cap height of a font.
|
|
||||||
#define HPGS_LF_FAC 1.75
|
|
||||||
#define HPGS_VSPACE_FAC 1.5
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command AD (Alternate font Definition)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_AD (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
while (!reader->eoc)
|
|
||||||
{
|
|
||||||
int kind;
|
|
||||||
if (hpgs_reader_read_int(reader,&kind)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->alternate_encoding))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->alternate_spacing))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->alternate_pitch))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->alternate_height))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->alternate_posture))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->alternate_weight))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->alternate_face))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SD (Standard font Definition)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SD (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
while (!reader->eoc)
|
|
||||||
{
|
|
||||||
int kind;
|
|
||||||
if (hpgs_reader_read_int(reader,&kind)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->default_encoding))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->default_spacing))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->default_pitch))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->default_height))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->default_posture))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->default_weight))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
if (hpgs_reader_read_int(reader,&reader->default_face))
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command CP (Character Plot)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_CP (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double w,h,ca,sa,spaces=0.0;
|
|
||||||
double lines=reader->current_text_line ? 1.0 : -1.0;
|
|
||||||
hpgs_point space_vec;
|
|
||||||
hpgs_point lf_vec;
|
|
||||||
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
reader->current_point = reader->cr_point;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&spaces)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&lines)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
w =
|
|
||||||
reader->current_char_size.x ? (1.5 * reader->current_char_size.x) :
|
|
||||||
(72.0 / (reader->alternate_font ?
|
|
||||||
reader->alternate_pitch :
|
|
||||||
reader->default_pitch ));
|
|
||||||
|
|
||||||
h =
|
|
||||||
reader->current_char_size.y ? reader->current_char_size.y :
|
|
||||||
(reader->alternate_font ?
|
|
||||||
reader->alternate_height :
|
|
||||||
reader->default_height );
|
|
||||||
|
|
||||||
ca = cos(reader->current_label_angle);
|
|
||||||
sa = sin(reader->current_label_angle);
|
|
||||||
|
|
||||||
switch (reader->current_text_path % 4)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
space_vec.x = ca * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
space_vec.y = sa * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.x = sa * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.y = -ca * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
space_vec.x = sa * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
space_vec.y = -ca * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.x = -ca * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.y = -sa * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
space_vec.x = -ca * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
space_vec.y = -sa * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.x = -sa * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.y = ca * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
break;
|
|
||||||
default: // 3
|
|
||||||
space_vec.x = -sa * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
space_vec.y = ca * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.x = ca * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.y = sa * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->current_text_line)
|
|
||||||
lines = -lines;
|
|
||||||
|
|
||||||
reader->current_point.x += space_vec.x * spaces;
|
|
||||||
reader->current_point.y += space_vec.y * spaces;
|
|
||||||
reader->current_point.x += lf_vec.x * lines;
|
|
||||||
reader->current_point.y += lf_vec.y * lines;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command DI (absolute DIrection)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_DI (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double run = 1.0;
|
|
||||||
double rise = 0.0;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&run)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&rise)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->current_label_angle = atan2(rise,run);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command DR (Relative Direction)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_DR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double run = 0.01;
|
|
||||||
double rise = 0.0;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&run)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&rise)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
run *= (reader->P2.x - reader->P1.x);
|
|
||||||
rise *= (reader->P2.y - reader->P1.y);
|
|
||||||
|
|
||||||
reader->current_label_angle = atan2(rise,run);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command DV (Define Variable Text path)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_DV (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_text_path = 0;
|
|
||||||
reader->current_text_line = 0;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&reader->current_text_path)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&reader->current_text_line)) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command ES (Extra Space)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_ES (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_extra_space.x = 0.0;
|
|
||||||
reader->current_extra_space.y = 0.0;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_double(reader,&reader->current_extra_space.x)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_double(reader,&reader->current_extra_space.y)) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command LO (Label Origin)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_LO (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_label_origin = 1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&reader->current_label_origin)) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SI (absolute character SIze)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SI (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_char_size.x = 0.0;
|
|
||||||
reader->current_char_size.y = 0.0;
|
|
||||||
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->current_char_size.x)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->current_char_size.y)) return -1;
|
|
||||||
|
|
||||||
reader->current_char_size.x *= 72.0 / 2.54;
|
|
||||||
reader->current_char_size.y *= 72.0 / 2.54;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SR (Relative character Size)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_char_size.x = 0.0;
|
|
||||||
reader->current_char_size.y = 0.0;
|
|
||||||
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->current_char_size.x)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->current_char_size.y)) return -1;
|
|
||||||
|
|
||||||
reader->current_char_size.x *= (reader->P2.x-reader->P1.x) * 0.01 * HP_TO_PT;
|
|
||||||
reader->current_char_size.y *= (reader->P2.y-reader->P1.y) * 0.01 * HP_TO_PT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SL (character SLant)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SL (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->current_slant = 0.0;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_double(reader,&reader->current_slant)) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SA (Select Alternate font)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SA (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->alternate_font = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SS (Select Standard font)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SS(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->alternate_font = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command DT (Define label Terminator)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_DT (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (reader->last_byte == ';')
|
|
||||||
{
|
|
||||||
reader->label_term = '\003';
|
|
||||||
reader->label_term_ignore = 1;
|
|
||||||
reader->eoc = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader->label_term = reader->last_byte;
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->last_byte == ',')
|
|
||||||
{
|
|
||||||
reader->label_term_ignore = 0;
|
|
||||||
|
|
||||||
while (isspace(reader->last_byte = hpgs_getc(reader->in))) ;
|
|
||||||
|
|
||||||
while (isdigit(reader->last_byte = hpgs_getc(reader->in)))
|
|
||||||
if (reader->last_byte != '0')
|
|
||||||
reader->label_term_ignore = 1;
|
|
||||||
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reader->label_term_ignore = 1;
|
|
||||||
|
|
||||||
while (isspace(reader->last_byte)) reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
|
|
||||||
if (isalpha(reader->last_byte) || reader->last_byte == HPGS_ESC)
|
|
||||||
reader->bytes_ignored = 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reader->last_byte != ';')
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->eoc = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SM (Symbol Mode)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SM (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_reader_check_param_end(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command LB (LaBel)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_LB (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
char str[HPGS_MAX_LABEL_SIZE];
|
|
||||||
double w,h,ca,sa;
|
|
||||||
hpgs_point left_vec;
|
|
||||||
hpgs_point up_vec;
|
|
||||||
hpgs_point space_vec;
|
|
||||||
hpgs_point lf_vec;
|
|
||||||
hpgs_point adj_vec;
|
|
||||||
int i0=0;
|
|
||||||
int ipos=0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_label_string(reader,str)) return -1;
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
w =
|
|
||||||
reader->current_char_size.x ? (1.5 * reader->current_char_size.x) :
|
|
||||||
(72.0 / (reader->alternate_font ?
|
|
||||||
reader->alternate_pitch :
|
|
||||||
reader->default_pitch ));
|
|
||||||
|
|
||||||
h =
|
|
||||||
reader->current_char_size.y ? reader->current_char_size.y :
|
|
||||||
(reader->alternate_font ?
|
|
||||||
reader->alternate_height :
|
|
||||||
reader->default_height );
|
|
||||||
|
|
||||||
ca = cos(reader->current_label_angle);
|
|
||||||
sa = sin(reader->current_label_angle);
|
|
||||||
|
|
||||||
left_vec.x = ca * w;
|
|
||||||
left_vec.y = sa * w;
|
|
||||||
|
|
||||||
up_vec.x = (reader->current_slant * ca - sa) * h;
|
|
||||||
up_vec.y = (reader->current_slant * sa + ca) * h;
|
|
||||||
|
|
||||||
switch (reader->current_text_path % 4)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
space_vec.x = ca * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
space_vec.y = sa * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.x = sa * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.y = -ca * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
adj_vec.x = sa * h;
|
|
||||||
adj_vec.y = -ca * h;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
space_vec.x = sa * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
space_vec.y = -ca * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.x = -ca * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.y = -sa * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
adj_vec.x = -ca * w;
|
|
||||||
adj_vec.y = -sa * w;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
space_vec.x = -ca * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
space_vec.y = -sa * (1.0+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.x = -sa * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.y = ca * (HPGS_LF_FAC+reader->current_extra_space.y) * h;
|
|
||||||
adj_vec.x = -sa * h;
|
|
||||||
adj_vec.y = ca * h;
|
|
||||||
break;
|
|
||||||
default: // 3
|
|
||||||
space_vec.x = -sa * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
space_vec.y = ca * (HPGS_VSPACE_FAC+reader->current_extra_space.y) * h;
|
|
||||||
lf_vec.x = ca * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
lf_vec.y = sa * (HPGS_LF_FAC+reader->current_extra_space.x) * w;
|
|
||||||
adj_vec.x = ca * w;
|
|
||||||
adj_vec.y = sa * w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->current_text_line)
|
|
||||||
{
|
|
||||||
lf_vec.x = -lf_vec.x;
|
|
||||||
lf_vec.y = -lf_vec.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_matrix_scale(&left_vec, &reader->page_matrix,&left_vec );
|
|
||||||
hpgs_matrix_scale(&up_vec, &reader->page_matrix,&up_vec );
|
|
||||||
hpgs_matrix_scale(&space_vec,&reader->page_matrix,&space_vec);
|
|
||||||
hpgs_matrix_scale(&lf_vec, &reader->page_matrix,&lf_vec );
|
|
||||||
hpgs_matrix_scale(&adj_vec, &reader->page_matrix,&adj_vec );
|
|
||||||
|
|
||||||
hpgs_point adj = { 0.0, 0.0 };
|
|
||||||
|
|
||||||
// got through the string and search for control characters.
|
|
||||||
for (i=0;i<=HPGS_MAX_LABEL_SIZE;i++)
|
|
||||||
{
|
|
||||||
if (i < HPGS_MAX_LABEL_SIZE && (unsigned char)str[i] >= 32)
|
|
||||||
{
|
|
||||||
if (ipos == 0 && reader->current_label_origin % 10 > 1)
|
|
||||||
{
|
|
||||||
// Everytime we start a new portion of the label,
|
|
||||||
// adapt the current point in order to meet the given label origin.
|
|
||||||
|
|
||||||
// lookahead for the new CR of EOS.
|
|
||||||
int j;
|
|
||||||
double x_adj,y_adj,nchars=0.0;
|
|
||||||
|
|
||||||
for (j=i;j<=HPGS_MAX_LABEL_SIZE;j++)
|
|
||||||
{
|
|
||||||
if (j < HPGS_MAX_LABEL_SIZE && (unsigned char)str[j] >= 32)
|
|
||||||
nchars+=1.0;
|
|
||||||
else
|
|
||||||
if (j >= HPGS_MAX_LABEL_SIZE || str[j] == 0 || str[j] == 13) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nchars && (reader->current_text_path % 2))
|
|
||||||
nchars -= reader->current_extra_space.y / (1.0 + reader->current_extra_space.y);
|
|
||||||
else
|
|
||||||
nchars -= reader->current_extra_space.x / (1.0 + reader->current_extra_space.x);
|
|
||||||
|
|
||||||
x_adj = -0.5 * nchars * ((reader->current_label_origin % 10 - 1) / 3);
|
|
||||||
y_adj = -0.5 * ((reader->current_label_origin % 10 - 1) % 3);
|
|
||||||
|
|
||||||
if (reader->current_label_origin / 10)
|
|
||||||
{
|
|
||||||
x_adj -= 0.25 * ((reader->current_label_origin % 10 - 1) / 3 - 1);
|
|
||||||
y_adj -= 0.25 * ((reader->current_label_origin % 10 - 1) % 3 - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
adj.x += x_adj * space_vec.x - y_adj * adj_vec.x;
|
|
||||||
adj.y += x_adj * space_vec.y - y_adj * adj_vec.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipos == 0)
|
|
||||||
switch (reader->current_text_path % 4)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
adj.x -= up_vec.x;
|
|
||||||
adj.y -= up_vec.y;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
adj.x -= left_vec.x + up_vec.x;
|
|
||||||
adj.y -= left_vec.y + up_vec.y;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
adj.x -= left_vec.x;
|
|
||||||
adj.y -= left_vec.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
++ipos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->current_point.x += adj.x;
|
|
||||||
reader->current_point.y += adj.y;
|
|
||||||
|
|
||||||
if (i>i0 &&
|
|
||||||
hpgs_reader_label(reader,str+i0,i-i0,
|
|
||||||
reader->alternate_font ?
|
|
||||||
reader->alternate_face :
|
|
||||||
reader->default_face,
|
|
||||||
reader->alternate_font ?
|
|
||||||
reader->alternate_encoding :
|
|
||||||
reader->default_encoding,
|
|
||||||
reader->alternate_font ?
|
|
||||||
reader->alternate_posture :
|
|
||||||
reader->default_posture,
|
|
||||||
reader->alternate_font ?
|
|
||||||
reader->alternate_weight :
|
|
||||||
reader->default_weight,
|
|
||||||
&left_vec,
|
|
||||||
&up_vec,
|
|
||||||
&space_vec))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
reader->current_point.x -= adj.x;
|
|
||||||
reader->current_point.y -= adj.y;
|
|
||||||
|
|
||||||
adj.x = 0.0;
|
|
||||||
adj.y = 0.0;
|
|
||||||
|
|
||||||
if (i >= HPGS_MAX_LABEL_SIZE || str[i] == 0) break;
|
|
||||||
|
|
||||||
i0 = i+1;
|
|
||||||
|
|
||||||
switch (str[i])
|
|
||||||
{
|
|
||||||
case 8: // backspace
|
|
||||||
reader->current_point.x -= space_vec.x;
|
|
||||||
reader->current_point.y -= space_vec.y;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9: // horizontal tab.
|
|
||||||
reader->current_point.x += space_vec.x * (8 - ipos % 8);
|
|
||||||
reader->current_point.y += space_vec.y * (8 - ipos % 8);
|
|
||||||
ipos += (8 - ipos % 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 10: // linefeed.
|
|
||||||
reader->cr_point.x += lf_vec.x;
|
|
||||||
reader->cr_point.y += lf_vec.y;
|
|
||||||
reader->current_point.x += lf_vec.x;
|
|
||||||
reader->current_point.y += lf_vec.y;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13: // carriage return.
|
|
||||||
reader->current_point.x = reader->cr_point.x;
|
|
||||||
reader->current_point.y = reader->cr_point.y;
|
|
||||||
ipos=0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 14: // shift out.
|
|
||||||
reader->alternate_font = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 15: // shift in.
|
|
||||||
reader->alternate_font = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (reader->verbosity >= 1)
|
|
||||||
hpgs_log(hpgs_i18n("LB: Ignoring unknown control character <%d>.\n"),
|
|
||||||
(int)str[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command MG (MessaGe)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_MG (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
char str[HPGS_MAX_LABEL_SIZE];
|
|
||||||
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_new_string(reader,str)) return -1;
|
|
||||||
|
|
||||||
if (reader->verbosity >= 1)
|
|
||||||
hpgs_log(hpgs_i18n("Message <%.*s>.\n"),HPGS_MAX_LABEL_SIZE,str);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,151 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsdevices.h 298 2006-03-05 18:18:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The private interfaces for the basic devices *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_DEVICES_H
|
|
||||||
#define __HPGS_DEVICES_H
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \file hpgsdevices.h
|
|
||||||
|
|
||||||
\brief The private interfaces for basic vector devices.
|
|
||||||
|
|
||||||
A header file, which declares the structures and functions internally
|
|
||||||
used for implementing the very basic implementations of \c hpgs_device.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @addtogroup device
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HPGS_PLOTSIZE_MAX_CLIP_DEPTH 16
|
|
||||||
|
|
||||||
/*! \brief A vector graphics device for plotsize calculating.
|
|
||||||
|
|
||||||
This structure implements a \c hpgs_device and is used to calculate
|
|
||||||
the bounding box of a vector graphics scenery.
|
|
||||||
*/
|
|
||||||
struct hpgs_plotsize_device_st {
|
|
||||||
hpgs_device inherited; //!< The base device structure.
|
|
||||||
|
|
||||||
hpgs_bool ignore_ps; //!< Do we ignore a PS command?
|
|
||||||
int clip_depth; //!< The depth of the current clip path stack.
|
|
||||||
|
|
||||||
hpgs_point moveto; //!< The position of the last moveto.
|
|
||||||
int deferred_moveto; //!< Do we have an unregistered moveto pending?
|
|
||||||
|
|
||||||
hpgs_bool do_linewidth; //!< Do we account for the current linewidth?
|
|
||||||
double linewidth; //!< Current linewidth.
|
|
||||||
|
|
||||||
hpgs_bbox clip_bbs[HPGS_PLOTSIZE_MAX_CLIP_DEPTH]; /*! The bounding boxes of the clip paths. */
|
|
||||||
|
|
||||||
hpgs_bbox path_bb; /*! The bounding box of the current path. */
|
|
||||||
hpgs_bbox page_bb; /*! The bounding box of the current page. */
|
|
||||||
hpgs_bbox global_bb; /*! The currently calculated overall bounding box. */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! A stack of page bounding boxes.
|
|
||||||
*/
|
|
||||||
hpgs_bbox *page_bbs; /*! The currently calculated overall bounding box. */
|
|
||||||
int n_page_bbs;
|
|
||||||
int page_bbs_alloc_size;
|
|
||||||
/*@} */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct hpgs_ps_media_size_st hpgs_ps_media_size;
|
|
||||||
|
|
||||||
/*! \brief A structure for storing a paper size.
|
|
||||||
|
|
||||||
This structure stores a PostScipt paper size.
|
|
||||||
*/
|
|
||||||
struct hpgs_ps_media_size_st
|
|
||||||
{
|
|
||||||
int width; //!< The width of the paper in pt.
|
|
||||||
int height; //!< The height of the paper in pt.
|
|
||||||
|
|
||||||
const char *name; //!< The name of this paper size, if it is a std paper size.
|
|
||||||
size_t usage; //!< The usage count of this paper size.
|
|
||||||
|
|
||||||
size_t hash; //!< A hash value for storing media sizes in a sorted vector.
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A vector graphics device for drawing to an eps file.
|
|
||||||
|
|
||||||
This structure implements a \c hpgs_device and is used to write
|
|
||||||
a scenery to an eps file.
|
|
||||||
*/
|
|
||||||
struct hpgs_eps_device_st {
|
|
||||||
hpgs_device inherited; //!< The base device structure.
|
|
||||||
|
|
||||||
hpgs_bbox doc_bb;
|
|
||||||
/*! The document bounding box used for multipage postscript files. */
|
|
||||||
|
|
||||||
hpgs_bbox page_bb;
|
|
||||||
/*! The bounding box of the current page. */
|
|
||||||
|
|
||||||
int n_pages;
|
|
||||||
/*! The number of pages. -1...we are writing individual eps files. */
|
|
||||||
|
|
||||||
char *filename; //!< The output filename.
|
|
||||||
|
|
||||||
hpgs_ostream *out; //!< The current page stream.
|
|
||||||
hpgs_bool page_setup; //!< Is the current page set up?
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! A stack of media sizes for multipage PostScript files.
|
|
||||||
The media sizes are sorted by their hash value.
|
|
||||||
*/
|
|
||||||
hpgs_ps_media_size *media_sizes; /*! The currently calculated overall bounding box. */
|
|
||||||
int n_media_sizes;
|
|
||||||
int media_sizes_alloc_size;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
hpgs_xrop3_func_t rop3; //!< The ROP3 transfer raster operation.
|
|
||||||
hpgs_palette_color pattern_color; //!< The color of the ROP3 pattern.
|
|
||||||
|
|
||||||
hpgs_color color; //!< The current output color.
|
|
||||||
};
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_cleanup_plugin_devices();
|
|
||||||
|
|
||||||
/*! @} */ /* end of group device */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // end of extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! __HPGS_DEVICES_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,296 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsfont.h 307 2006-03-07 08:45:04Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private header file for ttf font support. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_FONT_H__
|
|
||||||
#define __HPGS_FONT_H__
|
|
||||||
|
|
||||||
#include<hpgsmutex.h>
|
|
||||||
#include<stdint.h>
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_font_init();
|
|
||||||
HPGS_INTERNAL_API void hpgs_font_cleanup();
|
|
||||||
|
|
||||||
// The max. number of ttf tables to store.
|
|
||||||
#define HPGS_FONT_MAX_TTF_TABLES 32
|
|
||||||
|
|
||||||
typedef struct hpgs_font_header_st hpgs_font_header;
|
|
||||||
typedef struct hpgs_font_dentry_st hpgs_font_dentry;
|
|
||||||
typedef struct hpgs_font_table_entry_st hpgs_font_table_entry;
|
|
||||||
typedef struct hpgs_font_head_data_st hpgs_font_head_data;
|
|
||||||
typedef struct hpgs_font_hhea_data_st hpgs_font_hhea_data;
|
|
||||||
typedef struct hpgs_font_maxp_data_st hpgs_font_maxp_data;
|
|
||||||
typedef struct hpgs_font_longHorMetrics_st hpgs_font_longHorMetrics;
|
|
||||||
typedef struct hpgs_font_cmap_data_st hpgs_font_cmap_data;
|
|
||||||
typedef struct hpgs_font_cmap_code_range_st hpgs_font_cmap_code_range;
|
|
||||||
typedef struct hpgs_font_post_data_st hpgs_font_post_data;
|
|
||||||
typedef struct hpgs_font_glyph_point_st hpgs_font_glyph_point;
|
|
||||||
typedef struct hpgs_font_glyph_ref_st hpgs_font_glyph_ref;
|
|
||||||
typedef struct hpgs_font_glyph_data_st hpgs_font_glyph_data;
|
|
||||||
typedef struct hpgs_font_kern_pair_st hpgs_font_kern_pair;
|
|
||||||
|
|
||||||
|
|
||||||
struct hpgs_font_table_entry_st
|
|
||||||
{
|
|
||||||
uint32_t tag; /* Table name */
|
|
||||||
uint32_t checksum; /* for table */
|
|
||||||
uint32_t offset; /* to start of table in input file */
|
|
||||||
uint32_t length; /* length of table */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_head_data_st {
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t fontRevision;
|
|
||||||
uint32_t checkSumAdjustment;
|
|
||||||
uint32_t magicNumber;
|
|
||||||
uint16_t flags;
|
|
||||||
uint16_t unitsPerEm;
|
|
||||||
//int64_t created;
|
|
||||||
//int64_t modified;
|
|
||||||
int32_t created_low;
|
|
||||||
int32_t created_high;
|
|
||||||
int32_t modified_low;
|
|
||||||
int32_t modified_high;
|
|
||||||
int16_t xMin;
|
|
||||||
int16_t yMin;
|
|
||||||
int16_t xMax;
|
|
||||||
int16_t yMax;
|
|
||||||
uint16_t macStyle;
|
|
||||||
int16_t lowestRecPPEM;
|
|
||||||
int16_t fontDirectionHint;
|
|
||||||
int16_t indexToLocFormat;
|
|
||||||
int16_t glyphDataFormat;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_hhea_data_st {
|
|
||||||
uint32_t version;
|
|
||||||
int16_t ascent;
|
|
||||||
int16_t descent;
|
|
||||||
int16_t lineGap;
|
|
||||||
uint16_t advanceWidthMax;
|
|
||||||
int16_t minLeftSideBearing;
|
|
||||||
int16_t minRightSideBearing;
|
|
||||||
int16_t xMaxExtent;
|
|
||||||
int16_t caretSlopeRise;
|
|
||||||
int16_t caretSlopeRun;
|
|
||||||
int16_t caretOffset;
|
|
||||||
int16_t reserved1;
|
|
||||||
int16_t reserved2;
|
|
||||||
int16_t reserved3;
|
|
||||||
int16_t reserved4;
|
|
||||||
int16_t metricDataFormat;
|
|
||||||
uint16_t numOfLongHorMetrics;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_maxp_data_st {
|
|
||||||
uint32_t version;
|
|
||||||
uint16_t numGlyphs;
|
|
||||||
uint16_t maxPoints;
|
|
||||||
uint16_t maxContours;
|
|
||||||
uint16_t maxComponentPoints;
|
|
||||||
uint16_t maxComponentContours;
|
|
||||||
uint16_t maxZones;
|
|
||||||
uint16_t maxTwilightPoints;
|
|
||||||
uint16_t maxStorage;
|
|
||||||
uint16_t maxFunctionDefs;
|
|
||||||
uint16_t maxInstructionDefs;
|
|
||||||
uint16_t maxStackElements;
|
|
||||||
uint16_t maxSizeOfInstructions;
|
|
||||||
uint16_t maxComponentElements;
|
|
||||||
uint16_t maxComponentDepth;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_longHorMetrics_st
|
|
||||||
{
|
|
||||||
uint16_t advanceWidth;
|
|
||||||
int16_t leftSideBearing;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_cmap_code_range_st
|
|
||||||
{
|
|
||||||
uint16_t startCode;
|
|
||||||
uint16_t endCode;
|
|
||||||
uint16_t idDelta;
|
|
||||||
uint16_t idRangeOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_cmap_data_st
|
|
||||||
{
|
|
||||||
size_t ranges_sz;
|
|
||||||
hpgs_font_cmap_code_range *ranges;
|
|
||||||
|
|
||||||
size_t glyphIndexArray_sz;
|
|
||||||
uint16_t *glyphIndexArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_post_data_st
|
|
||||||
{
|
|
||||||
int32_t version; // 0x00020000 for version 2.0
|
|
||||||
int32_t italicAngle; // Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward).
|
|
||||||
int16_t underlinePosition; // This is the suggested distance of the top of the underline from the baseline (negative values indicate below baseline).
|
|
||||||
int16_t underlineThickness; // Suggested values for the underline thickness.
|
|
||||||
uint32_t isFixedPitch; // Set to 0 if the font is proportionally spaced, non-zero if the font is not proportionally spaced (i.e. monospaced).
|
|
||||||
uint32_t minMemType42; // Minimum memory usage when an OpenType font is downloaded.
|
|
||||||
uint32_t maxMemType42; // Maximum memory usage when an OpenType font is downloaded.
|
|
||||||
uint32_t minMemType1; // Minimum memory usage when an OpenType font is downloaded as a Type 1 font.
|
|
||||||
uint32_t maxMemType1; // Maximum memory usage when an OpenType font is downloaded as a Type 1 font.
|
|
||||||
uint16_t numberOfGlyphs; // Number of glyphs (this should be the same as numGlyphs in 'maxp' table).
|
|
||||||
|
|
||||||
const char **names; // pointer to the glyph names.
|
|
||||||
const char *name_data; // the buffer holding the actual data.
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HPGS_FONT_GLYPH_POINT_START 1
|
|
||||||
#define HPGS_FONT_GLYPH_POINT_ONCURVE 2
|
|
||||||
#define HPGS_FONT_GLYPH_POINT_CONTROL 3
|
|
||||||
|
|
||||||
struct hpgs_font_glyph_point_st
|
|
||||||
{
|
|
||||||
hpgs_point p;
|
|
||||||
int flags; // HPGS_FONT_GLYPH_POINT_*
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_glyph_ref_st
|
|
||||||
{
|
|
||||||
hpgs_matrix matrix; // transformation matrix
|
|
||||||
uint16_t gid; // the references glyph id.
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hpgs_font_glyph_data_st
|
|
||||||
{
|
|
||||||
hpgs_bbox bbox;
|
|
||||||
|
|
||||||
size_t points_sz;
|
|
||||||
hpgs_font_glyph_point *points;
|
|
||||||
|
|
||||||
size_t refs_sz;
|
|
||||||
size_t refs_alloc_sz;
|
|
||||||
hpgs_font_glyph_ref *refs;
|
|
||||||
|
|
||||||
size_t begin_kern_pair; /*!< The index of the first kern pair where this glyph id the left one. */
|
|
||||||
size_t end_kern_pair;/*!< The index of the first kern pair after \c begin_kern_pair where this glyph id is not the left one. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief A ttf kerning pair
|
|
||||||
*/
|
|
||||||
struct hpgs_font_kern_pair_st
|
|
||||||
{
|
|
||||||
uint16_t left_gid; /*!< The left glyph ID. */
|
|
||||||
uint16_t right_gid; /*!< The rightt glyph ID. */
|
|
||||||
|
|
||||||
double value; /*!< The correction of the advynce width in em. */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief A truetype font header.
|
|
||||||
|
|
||||||
This structure holds all the header information of a truetype font
|
|
||||||
and is used when scanning a fon directory as well as a part of an
|
|
||||||
open font file.
|
|
||||||
*/
|
|
||||||
struct hpgs_font_header_st
|
|
||||||
{
|
|
||||||
int32_t version; /*!< 0x00010000 */
|
|
||||||
uint16_t numtab; /*!< The number truetype tables in this file. */
|
|
||||||
uint16_t searchRange; /*!< (Max power of 2 <= numtab) *16 */
|
|
||||||
uint16_t entrySel; /*!< Log2(Max power of 2 <= numtab ) */
|
|
||||||
uint16_t rangeShift; /*!< numtab*16 - searchRange */
|
|
||||||
|
|
||||||
hpgs_font_table_entry tables[HPGS_FONT_MAX_TTF_TABLES]; /*!< The truetype table entries. */
|
|
||||||
|
|
||||||
int name_table; /*!< The position of the name table. */
|
|
||||||
int head_table; /*!< The position of the head table. */
|
|
||||||
int hhea_table; /*!< The position of the hhea table. */
|
|
||||||
int maxp_table; /*!< The position of the maxp table. */
|
|
||||||
int hmtx_table; /*!< The position of the hmtx table. */
|
|
||||||
int loca_table; /*!< The position of the loca table. */
|
|
||||||
int cmap_table; /*!< The position of the cmap table. */
|
|
||||||
int post_table; /*!< The position of the post table. */
|
|
||||||
int glyf_table; /*!< The position of the glyf table. */
|
|
||||||
int kern_table; /*!< The position of the kern table. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A truetype font.
|
|
||||||
|
|
||||||
This structure holds all details for operating on a truetype font
|
|
||||||
file. The font file is kept open by the font object during it's
|
|
||||||
lifetime, since we operate on the font file like on a database.
|
|
||||||
*/
|
|
||||||
struct hpgs_font_st
|
|
||||||
{
|
|
||||||
hpgs_istream *is; /*!< The input stream to operate on. */
|
|
||||||
|
|
||||||
// the file header.
|
|
||||||
hpgs_font_header header;
|
|
||||||
|
|
||||||
hpgs_font_head_data head_data; /*!< The head table. */
|
|
||||||
hpgs_font_hhea_data hhea_data; /*!< The hhea table. */
|
|
||||||
hpgs_font_maxp_data maxp_data; /*!< The maxp table. */
|
|
||||||
|
|
||||||
hpgs_font_longHorMetrics *hmtx_data;
|
|
||||||
/*!< The hmtx table. This array has a dimension of maxp_data.numGlyphs. */
|
|
||||||
|
|
||||||
uint32_t *loca_data; /*!< The loca table. */
|
|
||||||
size_t loca_data_sz; /*!< The size of the loca table. */
|
|
||||||
|
|
||||||
hpgs_font_cmap_data cmap_data; /*!< The cmap table. */
|
|
||||||
hpgs_font_post_data post_data; /*!< The post table. */
|
|
||||||
|
|
||||||
hpgs_font_kern_pair *kern_data;
|
|
||||||
size_t kern_data_sz; /*!< The size of the kern table. */
|
|
||||||
|
|
||||||
int *glyph_cache_positions;
|
|
||||||
/*!< The position of an individual glyph in \c glyph_cache or -1, if the glyph has not been cached yet.
|
|
||||||
This array has a dimension of maxp_data.numGlyphs
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t n_cached_glyphs; /*!< The number of actually cached glyphs. */
|
|
||||||
hpgs_font_glyph_data *glyph_cache; /*!< The cached glyphs. This array has a dimension of maxp_data.numGlyphs. */
|
|
||||||
|
|
||||||
hpgs_mutex_t mutex; /*!< The mutex to protec glyph access and reference counting. */
|
|
||||||
size_t nref; /*!< The reference count. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A truetype font directory entry.
|
|
||||||
|
|
||||||
This structure holds an entry in the font directory.
|
|
||||||
*/
|
|
||||||
struct hpgs_font_dentry_st {
|
|
||||||
|
|
||||||
char *font_name; /*!< The utf8-encoded name of the font. */
|
|
||||||
char *filename; /*!< The filename of the font. */
|
|
||||||
|
|
||||||
hpgs_font *font; /*!< The font object, if this font is cached. */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,629 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsglobal.c 338 2006-06-17 08:33:36Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Global resources of HPGS. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsdevices.h>
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <hpgsfont.h>
|
|
||||||
#include <hpgsi18n.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
static DWORD tls_handle = -1;
|
|
||||||
/* Use a separate heap for the error messages. This heap is
|
|
||||||
destroyed in hpgs_cleanup, so we risk no lost pointers. */
|
|
||||||
static HANDLE hHeap = 0;
|
|
||||||
|
|
||||||
/*! A counterpart of vsprintf, which allocates the result string
|
|
||||||
on the heap an is save against buffer overflows.
|
|
||||||
|
|
||||||
Returns 0, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
static char* vsprintf_hHeap (const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
/* Guess we need no more than 1024 bytes. */
|
|
||||||
int n, size = 1024;
|
|
||||||
char *p;
|
|
||||||
if ((p = HeapAlloc (hHeap,0,size)) == NULL)
|
|
||||||
return p;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Try to print in the allocated space. */
|
|
||||||
n = _vsnprintf (p, size, fmt, ap);
|
|
||||||
/* If that worked, return the string. */
|
|
||||||
if (n > -1 && n < size)
|
|
||||||
{ return p; }
|
|
||||||
/* Else try again with more space. */
|
|
||||||
if (n > -1) /* glibc 2.1 */
|
|
||||||
size = n+1; /* precisely what is needed */
|
|
||||||
else /* glibc 2.0 */
|
|
||||||
size *= 2; /* twice the old size */
|
|
||||||
|
|
||||||
{
|
|
||||||
char *np = HeapReAlloc (hHeap,0,p,size);
|
|
||||||
|
|
||||||
if (!np) { HeapFree(hHeap,0,p); return 0; }
|
|
||||||
p = np;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* sprintf_hHeap (const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = vsprintf_hHeap(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
static pthread_key_t key;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *hpgs_reader_prefix=0;
|
|
||||||
|
|
||||||
/*! This function has to be called before using any other
|
|
||||||
function of hpgs. It defines the path, where additional
|
|
||||||
files such as the truetype files for HPGL files or plugins
|
|
||||||
are stored.
|
|
||||||
|
|
||||||
Truetype fonts are searched in the path <prefix>/share/hpgs
|
|
||||||
|
|
||||||
The path is internally duplicated using \c strdup.
|
|
||||||
*/
|
|
||||||
void hpgs_init(const char *path)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
|
|
||||||
hpgs_reader_prefix = strdup(path);
|
|
||||||
|
|
||||||
if (!hpgs_reader_prefix) return;
|
|
||||||
|
|
||||||
// strip off trailing directory separators.
|
|
||||||
l = strlen(hpgs_reader_prefix);
|
|
||||||
|
|
||||||
if (l && hpgs_reader_prefix[l-1] == HPGS_PATH_SEPARATOR)
|
|
||||||
hpgs_reader_prefix[l-1] = '\0';
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
hHeap = HeapCreate(0,4096,128*1024);
|
|
||||||
tls_handle = TlsAlloc();
|
|
||||||
#else
|
|
||||||
pthread_key_create (&key,free);
|
|
||||||
#endif
|
|
||||||
#ifdef HPGS_HAVE_GETTEXT
|
|
||||||
hpgs_i18n_init();
|
|
||||||
#endif
|
|
||||||
hpgs_font_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! This function return a pointer to the installation prefix
|
|
||||||
set through \c hpgs_init. The returned string has any trailing
|
|
||||||
directory separator of the string passed to \c hpgs_init stripped
|
|
||||||
off.
|
|
||||||
*/
|
|
||||||
HPGS_API const char *hpgs_get_prefix()
|
|
||||||
{
|
|
||||||
if (hpgs_reader_prefix)
|
|
||||||
return hpgs_reader_prefix;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
return "C:\\Programme\\EV-i";
|
|
||||||
#else
|
|
||||||
#ifndef HPGS_DEFAULT_PREFIX
|
|
||||||
return "/usr/local";
|
|
||||||
#else
|
|
||||||
return HPGS_DEFAULT_PREFIX;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! This function has to be called atfer the last usage of hpgs.
|
|
||||||
It cleans up internally allocated resources.
|
|
||||||
*/
|
|
||||||
void hpgs_cleanup()
|
|
||||||
{
|
|
||||||
hpgs_font_cleanup();
|
|
||||||
|
|
||||||
hpgs_cleanup_plugin_devices();
|
|
||||||
|
|
||||||
if (hpgs_reader_prefix)
|
|
||||||
{
|
|
||||||
free(hpgs_reader_prefix);
|
|
||||||
hpgs_reader_prefix = 0;
|
|
||||||
}
|
|
||||||
#ifdef WIN32
|
|
||||||
TlsFree(tls_handle);
|
|
||||||
HeapDestroy(hHeap);
|
|
||||||
hHeap=0;
|
|
||||||
tls_handle=-1;
|
|
||||||
#else
|
|
||||||
hpgs_clear_error();
|
|
||||||
pthread_key_delete (key);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Get the value of the command line argument argv[0],
|
|
||||||
if the argument starts with \c opt.
|
|
||||||
|
|
||||||
This subroutine is useful when parsing command lines
|
|
||||||
like in the following loop:
|
|
||||||
|
|
||||||
\verbatim
|
|
||||||
int main(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
while (argc>1)
|
|
||||||
{
|
|
||||||
int narg = 1;
|
|
||||||
const char *value;
|
|
||||||
|
|
||||||
if (hpgs_get_arg_value("-r",argv,&value,&narg))
|
|
||||||
{
|
|
||||||
...parse value of option -r...
|
|
||||||
}
|
|
||||||
else if (hpgs_get_arg_value("-p",argv,&value,&narg))
|
|
||||||
{
|
|
||||||
...parse value of option -p...
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (argv[0][0] == '-')
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Error: Unknown option %s given.\n",argv[0]);
|
|
||||||
return usage();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv+=narg;
|
|
||||||
argc-=narg;
|
|
||||||
}
|
|
||||||
|
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
Returns \c HPGS_TRUE, if argv[0] starts with opt.
|
|
||||||
If \c *narg == 2, argv[0] is exactly \c opt and
|
|
||||||
\c *value points to \c argv[1].
|
|
||||||
If \c *narg == 1, argv[0] startwith \c opt and
|
|
||||||
\c *value points to \c argv[0]+strlen(opt).
|
|
||||||
|
|
||||||
Returns \c HPGS_FALSE, if argv[0] does not start with \c opt.
|
|
||||||
*/
|
|
||||||
hpgs_bool hpgs_get_arg_value(const char *opt, const char *argv[],
|
|
||||||
const char **value, int *narg)
|
|
||||||
{
|
|
||||||
int l = strlen(opt);
|
|
||||||
if (strncmp(opt,argv[0],l)!=0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (l == strlen(argv[0]))
|
|
||||||
{
|
|
||||||
*value = argv[1];
|
|
||||||
*narg = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*value = argv[0] + l;
|
|
||||||
*narg = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! This subroutine encapsulates the standard C library function \c realloc.
|
|
||||||
This is needed in order to aviod hassels when \c realloc returns
|
|
||||||
a null pointer and the original pointer is still needed for subsequent
|
|
||||||
deallocations.
|
|
||||||
|
|
||||||
\c itemsz is the size of the individual items in the array.
|
|
||||||
\c pptr is a pointer to the pointer holding te address of the array.
|
|
||||||
On success, \c *pptr points to the newly allocated array, otherwise
|
|
||||||
\c *pptr is untouched.
|
|
||||||
\c psz is a pointer to the allocated size of the array .
|
|
||||||
On success, *psz hold the new size \c nsz of the array,
|
|
||||||
otherwise \c *psz is untouched.
|
|
||||||
|
|
||||||
Returns 0 upon success or -1 if the system is out of memory.
|
|
||||||
*/
|
|
||||||
int hpgs_array_safe_resize (size_t itemsz, void **pptr, size_t *psz, size_t nsz)
|
|
||||||
{
|
|
||||||
void *np = realloc(*pptr,nsz*itemsz);
|
|
||||||
if (!np) return -1;
|
|
||||||
*pptr=np;
|
|
||||||
*psz=nsz;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! A counterpart of vsprintf, which allocates the result string
|
|
||||||
on the heap an is save against buffer overflows.
|
|
||||||
|
|
||||||
Returns 0, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
char* hpgs_vsprintf_malloc (const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
/* Guess we need no more than 1024 bytes. */
|
|
||||||
int n, size = 1024;
|
|
||||||
char *p;
|
|
||||||
if ((p = malloc (size)) == NULL)
|
|
||||||
return p;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Try to print in the allocated space. */
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
#ifdef WIN32
|
|
||||||
n = _vsnprintf (p, size, fmt, aq);
|
|
||||||
#else
|
|
||||||
n = vsnprintf (p, size, fmt, aq);
|
|
||||||
#endif
|
|
||||||
va_end(aq);
|
|
||||||
/* If that worked, return the string. */
|
|
||||||
if (n > -1 && n < size)
|
|
||||||
{ return p; }
|
|
||||||
/* Else try again with more space. */
|
|
||||||
if (n > -1) /* glibc 2.1 */
|
|
||||||
size = n+1; /* precisely what is needed */
|
|
||||||
else /* glibc 2.0 */
|
|
||||||
size *= 2; /* twice the old size */
|
|
||||||
|
|
||||||
{
|
|
||||||
char *np = realloc (p, size);
|
|
||||||
|
|
||||||
if (!np) { free(p); return 0; }
|
|
||||||
p = np;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! A counterpart of sprintf, which allocates the result string
|
|
||||||
on the heap an is save against buffer overflows.
|
|
||||||
|
|
||||||
Returns 0, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
char* hpgs_sprintf_malloc (const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = hpgs_vsprintf_malloc(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Constructs a filename on the heap for a file located in the
|
|
||||||
installation path passed to \c hpgs_init.
|
|
||||||
|
|
||||||
Returns 0, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
char *hpgs_share_filename(const char *rel_filename)
|
|
||||||
{
|
|
||||||
return hpgs_sprintf_malloc("%s%cshare%chpgs%c%s",
|
|
||||||
hpgs_get_prefix(),
|
|
||||||
HPGS_PATH_SEPARATOR,
|
|
||||||
HPGS_PATH_SEPARATOR,
|
|
||||||
HPGS_PATH_SEPARATOR,
|
|
||||||
rel_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Set the error message of the current thread to the given string.
|
|
||||||
|
|
||||||
Always returns -1.
|
|
||||||
*/
|
|
||||||
int hpgs_set_error(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = hpgs_set_verror(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Prepends the error message of the current thread with the given string.
|
|
||||||
this is useful, if you want to push context information
|
|
||||||
to the error message.
|
|
||||||
|
|
||||||
Always returns -1.
|
|
||||||
*/
|
|
||||||
int hpgs_error_ctxt(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
ret = hpgs_verror_ctxt(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Set the error message of the current thread to the given string.
|
|
||||||
|
|
||||||
Always returns -1.
|
|
||||||
*/
|
|
||||||
int hpgs_set_verror(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char *x;
|
|
||||||
#ifdef WIN32
|
|
||||||
x = (char *)TlsGetValue(tls_handle);
|
|
||||||
if (x) HeapFree(hHeap,0,x);
|
|
||||||
x = vsprintf_hHeap(fmt,ap);
|
|
||||||
TlsSetValue(tls_handle,x);
|
|
||||||
#else
|
|
||||||
x = (char *)pthread_getspecific (key);
|
|
||||||
if (x) free(x);
|
|
||||||
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
x = hpgs_vsprintf_malloc(fmt,aq);
|
|
||||||
va_end(aq);
|
|
||||||
|
|
||||||
pthread_setspecific (key,x);
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Clears the error message of the current thread.
|
|
||||||
*/
|
|
||||||
void hpgs_clear_error()
|
|
||||||
{
|
|
||||||
char *x;
|
|
||||||
#ifdef WIN32
|
|
||||||
x = (char *)TlsGetValue(tls_handle);
|
|
||||||
if (x) HeapFree(hHeap,0,x);
|
|
||||||
TlsSetValue(tls_handle,0);
|
|
||||||
#else
|
|
||||||
x = (char *)pthread_getspecific (key);
|
|
||||||
if (x) free(x);
|
|
||||||
pthread_setspecific (key,0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Checks, whther the error message of the current thread has been set.
|
|
||||||
*/
|
|
||||||
HPGS_API hpgs_bool hpgs_have_error()
|
|
||||||
{
|
|
||||||
char *x;
|
|
||||||
#ifdef WIN32
|
|
||||||
x = (char *)TlsGetValue(tls_handle);
|
|
||||||
#else
|
|
||||||
x = (char *)pthread_getspecific (key);
|
|
||||||
#endif
|
|
||||||
return x != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Prepends the error message of the current thread with the given string.
|
|
||||||
this is useful, if you want to push context information
|
|
||||||
to the error message.
|
|
||||||
|
|
||||||
Always returns -1.
|
|
||||||
*/
|
|
||||||
int hpgs_verror_ctxt(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char *x;
|
|
||||||
#ifdef WIN32
|
|
||||||
x = (char *)TlsGetValue(tls_handle);
|
|
||||||
|
|
||||||
if (!fmt) return -1;
|
|
||||||
|
|
||||||
char * new_p = vsprintf_hHeap(fmt,ap);
|
|
||||||
|
|
||||||
if (!new_p) return -1;
|
|
||||||
|
|
||||||
if (x)
|
|
||||||
{
|
|
||||||
char *tmp = sprintf_hHeap("%s: %s",new_p,x);
|
|
||||||
HeapFree(hHeap,0,new_p);
|
|
||||||
|
|
||||||
if (!tmp) return -1;
|
|
||||||
|
|
||||||
HeapFree(hHeap,0,x);
|
|
||||||
new_p = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
TlsSetValue(tls_handle,new_p);
|
|
||||||
|
|
||||||
#else
|
|
||||||
x = (char *)pthread_getspecific (key);
|
|
||||||
|
|
||||||
char * new_p = hpgs_vsprintf_malloc(fmt,ap);
|
|
||||||
|
|
||||||
if (!new_p) return -1;
|
|
||||||
|
|
||||||
if (x)
|
|
||||||
{
|
|
||||||
char *tmp = hpgs_sprintf_malloc("%s: %s",new_p,x);
|
|
||||||
free(new_p);
|
|
||||||
|
|
||||||
if (!tmp) return -1;
|
|
||||||
|
|
||||||
free(x);
|
|
||||||
new_p = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_setspecific (key,new_p);
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Get the error message of the current thread.
|
|
||||||
*/
|
|
||||||
const char *hpgs_get_error()
|
|
||||||
{
|
|
||||||
const char *ret;
|
|
||||||
#ifdef WIN32
|
|
||||||
ret = (char *)TlsGetValue(tls_handle);
|
|
||||||
#else
|
|
||||||
ret = (char *)pthread_getspecific (key);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!ret) ret = hpgs_i18n("(no error)");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void default_hpgs_logger(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
vfprintf(stderr,fmt,aq);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_logger_func_t static_logger = default_hpgs_logger;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Set the logging function for logging informational messages.
|
|
||||||
If \c func is NULL, the default logging function, which log to
|
|
||||||
\c stderr is restored.
|
|
||||||
|
|
||||||
Warning: This function is not thread-safe and should be called
|
|
||||||
just after \c hpgs_init() at the beginning of the program.
|
|
||||||
*/
|
|
||||||
void hpgs_set_logger(hpgs_logger_func_t func)
|
|
||||||
{
|
|
||||||
if (func)
|
|
||||||
static_logger = func;
|
|
||||||
else
|
|
||||||
static_logger = default_hpgs_logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Logs an informational message using the function set with
|
|
||||||
\c hpgs_set_logger(). If no function is set with \c hpgs_set_logger(),
|
|
||||||
the message is printed to \c stderr.
|
|
||||||
*/
|
|
||||||
void hpgs_log(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
static_logger(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Logs an informational message using the function set with
|
|
||||||
\c hpgs_set_logger(). If no function is set with \c hpgs_set_logger(),
|
|
||||||
the message is printed to \c stderr.
|
|
||||||
*/
|
|
||||||
void hpgs_vlog(const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
static_logger(fmt,aq);
|
|
||||||
va_end(aq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the character code at the given position in an utf-8 string.
|
|
||||||
The pointer \c (*p) is advanced to the next character after the current
|
|
||||||
position.
|
|
||||||
*/
|
|
||||||
int hpgs_next_utf8(const char **p)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (((unsigned char)**p & 0x80) == 0)
|
|
||||||
ret = **p;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Hit in the middle of a multibyte sequence
|
|
||||||
// -> return EOS.
|
|
||||||
if (((unsigned char)**p & 0xC0) == 0x80)
|
|
||||||
ret = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// true multibyte sequence
|
|
||||||
int mask = 0x20;
|
|
||||||
int need = 2;
|
|
||||||
ret = 0x1f;
|
|
||||||
|
|
||||||
while (**p & mask)
|
|
||||||
{ ret >>= 1; mask >>=1; ++need; }
|
|
||||||
|
|
||||||
ret &= **p;
|
|
||||||
|
|
||||||
while (--need)
|
|
||||||
{
|
|
||||||
++(*p);
|
|
||||||
if (((**p) & 0xc0) != 0x80) { return 0; }
|
|
||||||
ret = (ret << 6) | ((**p) & 0x3f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++(*p);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns the number of unicode characters contained in the first \c n bytes
|
|
||||||
of the given utf-8 string. If the null character is encountered, the
|
|
||||||
interpretation is stopped before the n'th byte.
|
|
||||||
|
|
||||||
if \c n == -1, the string is ultimatively search up to the first occurrence
|
|
||||||
of the null character.
|
|
||||||
|
|
||||||
The pointer \c (*p) is advanced to the next character after the current
|
|
||||||
position.
|
|
||||||
*/
|
|
||||||
HPGS_API int hpgs_utf8_strlen(const char *p, int n)
|
|
||||||
{
|
|
||||||
const char **pp = &p;
|
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
while ((n<0 || ((*pp) - p) < n) && hpgs_next_utf8(pp) != 0)
|
|
||||||
++ret;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsgstate.c 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the public API for the gstate. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgspaint.h>
|
|
||||||
#include<assert.h>
|
|
||||||
#include<string.h>
|
|
||||||
|
|
||||||
/*! Creates a new gstate on the heap.
|
|
||||||
Use \c hpgs_gstate_destroy in order to destroy the returned
|
|
||||||
gstate pointer.
|
|
||||||
|
|
||||||
A null pointer is returned, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
hpgs_gstate *hpgs_new_gstate()
|
|
||||||
{
|
|
||||||
hpgs_gstate *ret = (hpgs_gstate *)malloc(sizeof(hpgs_gstate));
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret->line_cap = hpgs_cap_butt;
|
|
||||||
ret->line_join = hpgs_join_miter;
|
|
||||||
ret->color.r = 0.0;
|
|
||||||
ret->color.g = 0.0;
|
|
||||||
ret->color.b = 0.0;
|
|
||||||
ret->miterlimit = 5.0;
|
|
||||||
ret->linewidth = 1.0;
|
|
||||||
ret->n_dashes = 0;
|
|
||||||
ret->dash_lengths = 0;
|
|
||||||
ret->dash_offset = 0.0;
|
|
||||||
// ROP3 function: destination = source or pattern.
|
|
||||||
ret->rop3 = 252;
|
|
||||||
ret->src_transparency = HPGS_TRUE;
|
|
||||||
ret->pattern_transparency = HPGS_TRUE;
|
|
||||||
|
|
||||||
ret->pattern_color.r = 0.0;
|
|
||||||
ret->pattern_color.g = 0.0;
|
|
||||||
ret->pattern_color.b = 0.0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Destroys a gstate created using \c hpgs_new_gstate.
|
|
||||||
*/
|
|
||||||
void hpgs_gstate_destroy(hpgs_gstate *gstate)
|
|
||||||
{
|
|
||||||
if (!gstate) return;
|
|
||||||
if (gstate->dash_lengths) free(gstate->dash_lengths);
|
|
||||||
free (gstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Sets the dashes of \c gstate. The passed array and offset
|
|
||||||
folow th esemantics of PostScipt's \c setdash command.
|
|
||||||
|
|
||||||
Return value:
|
|
||||||
\li 0 Success.
|
|
||||||
\li -1 The system is out of memory.
|
|
||||||
*/
|
|
||||||
int hpgs_gstate_setdash(hpgs_gstate *gstate,
|
|
||||||
const float *dash_lengths,
|
|
||||||
unsigned n_dashes, double offset)
|
|
||||||
{
|
|
||||||
if (gstate->dash_lengths) free(gstate->dash_lengths);
|
|
||||||
|
|
||||||
gstate->n_dashes = n_dashes;
|
|
||||||
gstate->dash_offset = offset;
|
|
||||||
|
|
||||||
if (gstate->n_dashes)
|
|
||||||
{
|
|
||||||
gstate->dash_lengths = (float *)malloc(sizeof(float)*gstate->n_dashes);
|
|
||||||
if (!gstate->dash_lengths)
|
|
||||||
{
|
|
||||||
gstate->n_dashes = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove(gstate->dash_lengths,dash_lengths,sizeof(float)*gstate->n_dashes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
gstate->dash_lengths = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsi18n.c 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private subroutines used by subroutines of the library. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsi18n.h>
|
|
||||||
|
|
||||||
#ifdef HPGS_HAVE_GETTEXT
|
|
||||||
|
|
||||||
#define HPGS_I18N_DOMAIN "hpgs"
|
|
||||||
|
|
||||||
void hpgs_i18n_init()
|
|
||||||
{
|
|
||||||
char *sp = hpgs_sprintf_malloc("%s%cshare%clocale",
|
|
||||||
hpgs_get_prefix(),
|
|
||||||
HPGS_PATH_SEPARATOR,
|
|
||||||
HPGS_PATH_SEPARATOR);
|
|
||||||
|
|
||||||
if (!sp) return;
|
|
||||||
|
|
||||||
bindtextdomain(HPGS_I18N_DOMAIN,sp);
|
|
||||||
free(sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *hpgs_i18n(const char *msg)
|
|
||||||
{
|
|
||||||
return dgettext(HPGS_I18N_DOMAIN,msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *hpgs_i18n_n(const char *msg,
|
|
||||||
const char *msg_plural,
|
|
||||||
unsigned long n)
|
|
||||||
{
|
|
||||||
return dngettext(HPGS_I18N_DOMAIN,msg,msg_plural,n);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
const char *hpgs_i18n(const char *msg)
|
|
||||||
{ return msg; }
|
|
||||||
|
|
||||||
const char *hpgs_i18n_n(const char *msg,
|
|
||||||
const char *msg_plural,
|
|
||||||
unsigned long n)
|
|
||||||
{ return n==1 ? msg : msg_plural; }
|
|
||||||
|
|
||||||
#endif // HPGS_HAVE_GETTEXT
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsi18n.h 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private subroutines used by i18n facilities of the library. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_I18N_H__
|
|
||||||
#define __HPGS_I18N_H__
|
|
||||||
|
|
||||||
#include <hpgs.h>
|
|
||||||
|
|
||||||
#ifdef HPGS_HAVE_GETTEXT
|
|
||||||
|
|
||||||
#include <libintl.h>
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_i18n_init();
|
|
||||||
#endif // HPGS_HAVE_GETTEXT
|
|
||||||
|
|
||||||
#endif // ! __HPGS_I18N_H__
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsimage.h 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private declarations for images. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_IMAGE_H__
|
|
||||||
#define __HPGS_IMAGE_H__
|
|
||||||
|
|
||||||
#include <hpgs.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief An concrete pixel image.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_png_image and
|
|
||||||
implements \c hpgs_image. The storage format is similar
|
|
||||||
to the format used by \c libpng, so the image may be written
|
|
||||||
to png file using \c hpgs_png_image_write.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @addtogroup image
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
struct hpgs_png_image_st {
|
|
||||||
hpgs_image inherited;
|
|
||||||
|
|
||||||
int depth; //!< The bit depth of the image.
|
|
||||||
int color_type; //!< The color type.
|
|
||||||
int bytes_per_row; //!< The number of bytes per row of the pixel data.
|
|
||||||
int compression; //!< The compression used for writing the image in the range from 0 to 9.
|
|
||||||
|
|
||||||
unsigned char *data; //!< The pixel data.
|
|
||||||
|
|
||||||
hpgs_rop3_func_t rop3; //!< The ROP3 raster operation.
|
|
||||||
hpgs_palette_color pattern_color; //!< The color of the ROP3 pattern.
|
|
||||||
|
|
||||||
unsigned res_x; //!< The number of pixels per meter in x-direction, or 0 if unknown.
|
|
||||||
unsigned res_y; //!< The number of pixels per meter in y-direction, or 0 if unknown.
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @} */ /* end of group reader */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // end of extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ! __HPGS_IMAGE_H__
|
|
||||||
@@ -1,551 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsimagerop.c 372 2007-01-14 18:16:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the ROP3 clip frame extraction from images. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgs.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#if defined ( __MINGW32__ ) || defined ( _MSC_VER )
|
|
||||||
#include<malloc.h>
|
|
||||||
#else
|
|
||||||
#include<alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define HPGS_IMAGE_ROP_DEBUG
|
|
||||||
|
|
||||||
typedef struct hpgs_img_clip_seg_st hpgs_img_clip_seg;
|
|
||||||
|
|
||||||
struct hpgs_img_clip_seg_st
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
int i_vert;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct hpgs_img_clip_line_st hpgs_img_clip_line;
|
|
||||||
|
|
||||||
struct hpgs_img_clip_line_st
|
|
||||||
{
|
|
||||||
int i0;
|
|
||||||
int j0;
|
|
||||||
|
|
||||||
int i1;
|
|
||||||
int j1;
|
|
||||||
|
|
||||||
int key;
|
|
||||||
int usage;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MK_LINE_KEY(i,j) ((j)+(img->width+1)*(i))
|
|
||||||
|
|
||||||
static int compare_clip_lines (const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const hpgs_img_clip_line *la = (const hpgs_img_clip_line *)a;
|
|
||||||
const hpgs_img_clip_line *lb = (const hpgs_img_clip_line *)b;
|
|
||||||
|
|
||||||
if (la->key < lb->key) return -1;
|
|
||||||
if (la->key > lb->key) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int grow_clip_lines (hpgs_device *device,
|
|
||||||
hpgs_img_clip_line **clip_lines,
|
|
||||||
size_t *clip_lines_sz)
|
|
||||||
{
|
|
||||||
size_t nsz = *clip_lines_sz*2;
|
|
||||||
hpgs_img_clip_line *ncl=realloc(*clip_lines,nsz*sizeof(hpgs_img_clip_line));
|
|
||||||
|
|
||||||
if (!ncl)
|
|
||||||
return hpgs_set_error(hpgs_i18n("hpgs_image_rop3_clip: Out of memory growing temporary storage."));
|
|
||||||
|
|
||||||
*clip_lines = ncl;
|
|
||||||
*clip_lines_sz = nsz;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets a clip frame to the given device, which encloses all regions
|
|
||||||
of the device, which are cover by the image taking into account
|
|
||||||
the given ROP3 transfer function.
|
|
||||||
|
|
||||||
The argument \c data must contain a pointer to a two-dimensional
|
|
||||||
array of raw pixels of the size of the image. This array is filled
|
|
||||||
with pixel values as if the image has been painted to a white
|
|
||||||
destination area using the given ROP3 function.
|
|
||||||
|
|
||||||
Return values:
|
|
||||||
\li 0 The clip frame is empty, no operation has been performed on
|
|
||||||
the output device.
|
|
||||||
|
|
||||||
\li 1 The clip frame is not empty, the clip path has been
|
|
||||||
set to the output device using clipsave/moveto/lineto/clip
|
|
||||||
operations.
|
|
||||||
|
|
||||||
\li 2 The clip frame covers the whole image, no operation has been
|
|
||||||
performed on the output device.
|
|
||||||
|
|
||||||
\li 3 The clip frame is not empty, the visible pixels have all the same color
|
|
||||||
and clip path has been set to the output device using
|
|
||||||
moveto/lineto/setrgbcolor/fill operations. The image does not have to be
|
|
||||||
transferred by subsequent functions, the rgb color of the device has been
|
|
||||||
altered.
|
|
||||||
|
|
||||||
\li -1 An error occured on the output device.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int hpgs_image_rop3_clip(hpgs_device *device,
|
|
||||||
hpgs_palette_color *data,
|
|
||||||
const hpgs_image *img,
|
|
||||||
const hpgs_point *ll, const hpgs_point *lr,
|
|
||||||
const hpgs_point *ur,
|
|
||||||
const hpgs_palette_color *p,
|
|
||||||
hpgs_xrop3_func_t xrop3)
|
|
||||||
{
|
|
||||||
// The upper bound for clip_lines_sz is (w+1)*(h+1)*2.
|
|
||||||
// This formula is chosen so, that for w==1 and h==1,
|
|
||||||
// this result is achieved. For larger pictures, we
|
|
||||||
// use 1/8th of the upper bound, which is pretty conservative.
|
|
||||||
// If not doing so, the algorithm easily consumes up to 1GB or more,
|
|
||||||
// which is too much for alloca, too. So this estimation combined
|
|
||||||
// with the usage of malloc should make the code robust.
|
|
||||||
size_t clip_lines_sz = ((img->width+1)*(img->height+1)+31)/4;
|
|
||||||
|
|
||||||
hpgs_img_clip_line *clip_lines = (hpgs_img_clip_line *)
|
|
||||||
malloc(sizeof(hpgs_img_clip_line)*clip_lines_sz);
|
|
||||||
|
|
||||||
hpgs_img_clip_seg *segs0 = (hpgs_img_clip_seg *)
|
|
||||||
hpgs_alloca(sizeof(hpgs_img_clip_seg)*(img->width+1));
|
|
||||||
|
|
||||||
hpgs_img_clip_seg *segs1 = (hpgs_img_clip_seg *)
|
|
||||||
hpgs_alloca(sizeof(hpgs_img_clip_seg)*(img->width+1));
|
|
||||||
|
|
||||||
if (!clip_lines || !segs0 || !segs1)
|
|
||||||
return hpgs_set_error(hpgs_i18n("hpgs_image_rop3_clip: Out of memory allocating temporary storage."));
|
|
||||||
|
|
||||||
int n_clip_lines = 0;
|
|
||||||
int ret = -1;
|
|
||||||
int i_seg0,n_segs0 = 0;
|
|
||||||
int i_seg1,n_segs1 = 0;
|
|
||||||
|
|
||||||
hpgs_point ul;
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
hpgs_bool all_visible = HPGS_TRUE;
|
|
||||||
hpgs_palette_color *first_visible_pixel = 0;
|
|
||||||
hpgs_bool single_color = HPGS_FALSE;
|
|
||||||
|
|
||||||
ul.x = ll->x + (ur->x - lr->x);
|
|
||||||
ul.y = ll->y + (ur->y - lr->y);
|
|
||||||
|
|
||||||
// first, accumulate lines.
|
|
||||||
for (i=0;i<img->height+1;++i)
|
|
||||||
{
|
|
||||||
// cut the current raster line
|
|
||||||
int t_last = 1;
|
|
||||||
n_segs1 = 0;
|
|
||||||
|
|
||||||
// this is here in order to construct all lines
|
|
||||||
// for the very last grid line
|
|
||||||
if (i<img->height)
|
|
||||||
{
|
|
||||||
for (j=0;j<img->width;++j)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
hpgs_paint_color s;
|
|
||||||
unsigned r,g,b;
|
|
||||||
|
|
||||||
hpgs_image_get_pixel(img,j,i,&s,0);
|
|
||||||
|
|
||||||
r = xrop3(s.r,p->r);
|
|
||||||
g = xrop3(s.g,p->g);
|
|
||||||
b = xrop3(s.b,p->b);
|
|
||||||
|
|
||||||
// transparent ?
|
|
||||||
t = (r == 0x00ff && g == 0x00ff && b == 0x00ff);
|
|
||||||
|
|
||||||
if (t != t_last) // last pixel different transparency ?
|
|
||||||
{
|
|
||||||
segs1[n_segs1].j = j;
|
|
||||||
segs1[n_segs1].i_vert = -1;
|
|
||||||
++n_segs1;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_last = t;
|
|
||||||
|
|
||||||
data->r = (unsigned char)r;
|
|
||||||
data->g = (unsigned char)g;
|
|
||||||
data->b = (unsigned char)b;
|
|
||||||
|
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
if (!first_visible_pixel)
|
|
||||||
{
|
|
||||||
first_visible_pixel = data;
|
|
||||||
single_color = HPGS_TRUE;
|
|
||||||
}
|
|
||||||
else if (single_color &&
|
|
||||||
(first_visible_pixel->r != data->r ||
|
|
||||||
first_visible_pixel->g != data->g ||
|
|
||||||
first_visible_pixel->b != data->b ))
|
|
||||||
single_color = HPGS_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
++data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_segs1 != 1 || segs1[0].j > 0)
|
|
||||||
all_visible = HPGS_FALSE;
|
|
||||||
|
|
||||||
// close trailing visible segment.
|
|
||||||
if (t_last == 0)
|
|
||||||
{
|
|
||||||
segs1[n_segs1].j = j;
|
|
||||||
segs1[n_segs1].i_vert = -1;
|
|
||||||
++n_segs1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(n_segs1 <= (img->width+1));
|
|
||||||
|
|
||||||
#ifdef HPGS_IMAGE_ROP_DEBUG
|
|
||||||
hpgs_log("i=%d: segs1:",i);
|
|
||||||
|
|
||||||
for (j=0;j<n_segs1;++j)
|
|
||||||
hpgs_log("%c%d",j?',':' ',segs1[j].j);
|
|
||||||
hpgs_log("\n");
|
|
||||||
|
|
||||||
j=n_clip_lines;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// construct lines.
|
|
||||||
i_seg0 = 0;
|
|
||||||
i_seg1 = 0;
|
|
||||||
t_last = -1;
|
|
||||||
|
|
||||||
while (i_seg0 < n_segs0 || i_seg1 < n_segs1)
|
|
||||||
{
|
|
||||||
if (i_seg1 >= n_segs1 || (i_seg0 < n_segs0 && segs0[i_seg0].j < segs1[i_seg1].j))
|
|
||||||
{
|
|
||||||
// horizontal line.
|
|
||||||
if (t_last >= 0)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i;
|
|
||||||
clip_lines[n_clip_lines].i1 = i;
|
|
||||||
// check for the orientation.
|
|
||||||
if (i_seg0 & 1)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = t_last;
|
|
||||||
clip_lines[n_clip_lines].j1 = segs0[i_seg0].j;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = segs0[i_seg0].j;
|
|
||||||
clip_lines[n_clip_lines].j1 = t_last;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++n_clip_lines >= clip_lines_sz &&
|
|
||||||
grow_clip_lines(device,&clip_lines,&clip_lines_sz))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
t_last = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
t_last = segs0[i_seg0].j;
|
|
||||||
|
|
||||||
|
|
||||||
++i_seg0;
|
|
||||||
}
|
|
||||||
else if (i_seg0 >= n_segs0 || segs1[i_seg1].j < segs0[i_seg0].j)
|
|
||||||
{
|
|
||||||
// horizontal line.
|
|
||||||
if (t_last >= 0)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i;
|
|
||||||
clip_lines[n_clip_lines].i1 = i;
|
|
||||||
// check for the orientation.
|
|
||||||
if (i_seg1 & 1)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = segs1[i_seg1].j;
|
|
||||||
clip_lines[n_clip_lines].j1 = t_last;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = t_last;
|
|
||||||
clip_lines[n_clip_lines].j1 = segs1[i_seg1].j;
|
|
||||||
}
|
|
||||||
if (++n_clip_lines >= clip_lines_sz &&
|
|
||||||
grow_clip_lines(device,&clip_lines,&clip_lines_sz))
|
|
||||||
goto cleanup;
|
|
||||||
t_last = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
t_last = segs1[i_seg1].j;
|
|
||||||
|
|
||||||
// create vertical line.
|
|
||||||
clip_lines[n_clip_lines].j0 = segs1[i_seg1].j;
|
|
||||||
clip_lines[n_clip_lines].j1 = segs1[i_seg1].j;
|
|
||||||
|
|
||||||
// check for the orientation.
|
|
||||||
if (i_seg1 & 1)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i+1;
|
|
||||||
clip_lines[n_clip_lines].i1 = i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i;
|
|
||||||
clip_lines[n_clip_lines].i1 = i+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
segs1[i_seg1].i_vert = n_clip_lines;
|
|
||||||
if (++n_clip_lines >= clip_lines_sz &&
|
|
||||||
grow_clip_lines(device,&clip_lines,&clip_lines_sz))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
++i_seg1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(segs0[i_seg0].j == segs1[i_seg1].j);
|
|
||||||
|
|
||||||
// horizontal line.
|
|
||||||
if (t_last >= 0)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i;
|
|
||||||
clip_lines[n_clip_lines].i1 = i;
|
|
||||||
// check for the orientation.
|
|
||||||
if (i_seg1 & 1)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = segs1[i_seg1].j;
|
|
||||||
clip_lines[n_clip_lines].j1 = t_last;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].j0 = t_last;
|
|
||||||
clip_lines[n_clip_lines].j1 = segs1[i_seg1].j;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++n_clip_lines >= clip_lines_sz &&
|
|
||||||
grow_clip_lines(device,&clip_lines,&clip_lines_sz))
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((i_seg0 & 1) == (i_seg1 & 1))
|
|
||||||
{
|
|
||||||
// extend segment
|
|
||||||
int il = segs0[i_seg0].i_vert;
|
|
||||||
if (i_seg1 & 1)
|
|
||||||
clip_lines[il].i0 = i+1;
|
|
||||||
else
|
|
||||||
clip_lines[il].i1= i+1;
|
|
||||||
|
|
||||||
segs1[i_seg1].i_vert = il;
|
|
||||||
t_last = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// create new segment.
|
|
||||||
clip_lines[n_clip_lines].j0 = segs1[i_seg1].j;
|
|
||||||
clip_lines[n_clip_lines].j1 = segs1[i_seg1].j;
|
|
||||||
|
|
||||||
if (i_seg1 & 1)
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i+1;
|
|
||||||
clip_lines[n_clip_lines].i1 = i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clip_lines[n_clip_lines].i0 = i;
|
|
||||||
clip_lines[n_clip_lines].i1 = i+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
segs1[i_seg1].i_vert = n_clip_lines;
|
|
||||||
|
|
||||||
if (++n_clip_lines >= clip_lines_sz &&
|
|
||||||
grow_clip_lines(device,&clip_lines,&clip_lines_sz))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
t_last = segs1[i_seg1].j;
|
|
||||||
}
|
|
||||||
|
|
||||||
++i_seg0;
|
|
||||||
++i_seg1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_IMAGE_ROP_DEBUG
|
|
||||||
hpgs_log("i=%d: lines: ",i);
|
|
||||||
|
|
||||||
for (;j<n_clip_lines;++j)
|
|
||||||
hpgs_log("(%d,%d,%d,%d)",
|
|
||||||
clip_lines[j].i0,clip_lines[j].j0,
|
|
||||||
clip_lines[j].i1,clip_lines[j].j1);
|
|
||||||
hpgs_log("\n");
|
|
||||||
#endif
|
|
||||||
assert (t_last == -1);
|
|
||||||
|
|
||||||
// swap clip segment caches
|
|
||||||
{
|
|
||||||
hpgs_img_clip_seg *tmp = segs0;
|
|
||||||
segs0=segs1;
|
|
||||||
segs1=tmp;
|
|
||||||
}
|
|
||||||
n_segs0 = n_segs1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_IMAGE_ROP_DEBUG
|
|
||||||
hpgs_log("clip_img: n_clip_lines,all_visible = %d,%d.\n",
|
|
||||||
n_clip_lines,all_visible);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (n_clip_lines <= 0) { ret = 0; goto cleanup; }
|
|
||||||
if (all_visible && !single_color) { ret = 2; goto cleanup; }
|
|
||||||
|
|
||||||
assert(n_clip_lines <= (img->width+1)*(img->height+1)*2);
|
|
||||||
|
|
||||||
// OK, now create the lookup key of the lines.
|
|
||||||
for (i=0;i<n_clip_lines;++i)
|
|
||||||
{
|
|
||||||
clip_lines[i].key = MK_LINE_KEY(clip_lines[i].i0,clip_lines[i].j0);
|
|
||||||
clip_lines[i].usage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort the table
|
|
||||||
qsort(clip_lines,n_clip_lines,sizeof(hpgs_img_clip_line),compare_clip_lines);
|
|
||||||
|
|
||||||
if (!single_color && hpgs_clipsave(device)) goto cleanup;
|
|
||||||
|
|
||||||
// now construct the clip path.
|
|
||||||
for (i = 0;i<n_clip_lines;++i)
|
|
||||||
{
|
|
||||||
hpgs_img_clip_line *line = clip_lines+i;
|
|
||||||
int iline = 0;
|
|
||||||
|
|
||||||
if (line->usage) continue;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
hpgs_point p;
|
|
||||||
int key,i0,i1;
|
|
||||||
|
|
||||||
p.x = ul.x +
|
|
||||||
line->j0 * (lr->x - ll->x) / img->width +
|
|
||||||
line->i0 * (lr->x - ur->x) / img->height ;
|
|
||||||
|
|
||||||
p.y = ul.y +
|
|
||||||
line->j0 * (lr->y - ll->y) / img->width +
|
|
||||||
line->i0 * (lr->y - ur->y) / img->height ;
|
|
||||||
|
|
||||||
key = MK_LINE_KEY(line->i1,line->j1);
|
|
||||||
|
|
||||||
if (iline)
|
|
||||||
{
|
|
||||||
if (hpgs_lineto(device,&p)) goto cleanup;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hpgs_moveto(device,&p)) goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_IMAGE_ROP_DEBUG
|
|
||||||
hpgs_log("(%d,%d,%d,%d)",
|
|
||||||
line->i0,line->j0,
|
|
||||||
line->i1,line->j1);
|
|
||||||
#endif
|
|
||||||
++iline;
|
|
||||||
line->usage=1;
|
|
||||||
|
|
||||||
// binary search
|
|
||||||
i0 = 0;
|
|
||||||
i1 = n_clip_lines;
|
|
||||||
|
|
||||||
while (i1>i0)
|
|
||||||
{
|
|
||||||
int ii = i0+(i1-i0)/2;
|
|
||||||
|
|
||||||
if (clip_lines[ii].key < key)
|
|
||||||
i0 = ii+1;
|
|
||||||
else
|
|
||||||
i1 = ii;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (clip_lines[i0].usage &&
|
|
||||||
i0 < n_clip_lines-1 &&
|
|
||||||
clip_lines[i0+1].key == key)
|
|
||||||
++i0;
|
|
||||||
|
|
||||||
assert(i0 < n_clip_lines && key == clip_lines[i0].key);
|
|
||||||
|
|
||||||
line = clip_lines+i0;
|
|
||||||
|
|
||||||
assert (line);
|
|
||||||
|
|
||||||
if (line->usage && line < clip_lines + n_clip_lines &&
|
|
||||||
line[1].key == key)
|
|
||||||
++line;
|
|
||||||
}
|
|
||||||
while (!line->usage);
|
|
||||||
|
|
||||||
assert (line->i0 == clip_lines[i].i0 &&
|
|
||||||
line->j0 == clip_lines[i].j0 );
|
|
||||||
|
|
||||||
#ifdef HPGS_IMAGE_ROP_DEBUG
|
|
||||||
hpgs_log("\n");
|
|
||||||
#endif
|
|
||||||
if (hpgs_closepath(device)) goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (single_color)
|
|
||||||
{
|
|
||||||
hpgs_color c;
|
|
||||||
|
|
||||||
c.r = first_visible_pixel->r / 255.0;
|
|
||||||
c.g = first_visible_pixel->g / 255.0;
|
|
||||||
c.b = first_visible_pixel->b / 255.0;
|
|
||||||
|
|
||||||
if (hpgs_setrgbcolor(device,&c)) goto cleanup;
|
|
||||||
if (hpgs_fill(device,HPGS_FALSE)) goto cleanup;
|
|
||||||
if (hpgs_newpath(device)) goto cleanup;
|
|
||||||
|
|
||||||
ret = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hpgs_clip(device,HPGS_FALSE)) goto cleanup;
|
|
||||||
if (hpgs_newpath(device)) goto cleanup;
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (clip_lines) free(clip_lines);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,278 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsistream.c 343 2006-08-18 16:48:09Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementations of input streams. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgs.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
static int file_seek (FILE *file, size_t pos)
|
|
||||||
{
|
|
||||||
return fseek(file,pos,SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int file_seekend (FILE *file, size_t pos)
|
|
||||||
{
|
|
||||||
return fseek(file,-(long)pos,SEEK_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int file_tell (FILE *file, size_t *pos)
|
|
||||||
{
|
|
||||||
long pp=ftell(file);
|
|
||||||
|
|
||||||
if (pp<0) return -1;
|
|
||||||
|
|
||||||
*pos = pp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \defgroup base Basic facilities.
|
|
||||||
|
|
||||||
This module contains structures for operating on abstract input streams
|
|
||||||
as well as color structures and a 2D point.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static hpgs_istream_vtable file_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_istream_getc_func_t) getc,
|
|
||||||
(hpgs_istream_ungetc_func_t) ungetc,
|
|
||||||
(hpgs_istream_close_func_t) fclose,
|
|
||||||
(hpgs_istream_iseof_func_t) feof,
|
|
||||||
(hpgs_istream_iserror_func_t) ferror,
|
|
||||||
(hpgs_istream_seek_func_t) file_seek,
|
|
||||||
(hpgs_istream_tell_func_t) file_tell,
|
|
||||||
(hpgs_istream_read_func_t) fread,
|
|
||||||
(hpgs_istream_seekend_func_t) file_seekend
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Returns a new \c hpgs_istream created on the heap,
|
|
||||||
which operates on a file, which is opened by this call
|
|
||||||
in read-only mode.
|
|
||||||
|
|
||||||
Returns a null pointer, when an I/O error occurrs.
|
|
||||||
In this case, details about the the error can be retrieved
|
|
||||||
using \c errno.
|
|
||||||
*/
|
|
||||||
hpgs_istream *hpgs_new_file_istream(const char *fn)
|
|
||||||
{
|
|
||||||
FILE *in = fopen (fn,"rb");
|
|
||||||
hpgs_istream *ret = 0;
|
|
||||||
|
|
||||||
if (!in) return 0;
|
|
||||||
|
|
||||||
ret = (hpgs_istream *)malloc(sizeof(hpgs_istream));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
fclose(in);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->stream = in;
|
|
||||||
ret->vtable = &file_vtable;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* memory stream implementation functions. */
|
|
||||||
typedef struct hpgs_mem_istream_stream_st hpgs_mem_istream_stream;
|
|
||||||
|
|
||||||
struct hpgs_mem_istream_stream_st
|
|
||||||
{
|
|
||||||
const unsigned char *data;
|
|
||||||
const unsigned char *gptr;
|
|
||||||
const unsigned char *eptr;
|
|
||||||
int errflg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mem_getc (hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
ret=EOF;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (stream->gptr >= stream->eptr)
|
|
||||||
ret = EOF;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = *stream->gptr;
|
|
||||||
++stream->gptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_ungetc (int c, hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->errflg) return -1;
|
|
||||||
if (stream->gptr <= stream->data) { stream->errflg = 1; return -1; }
|
|
||||||
--stream->gptr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_close (hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_iseof (hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->gptr >= stream->eptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_iserror (hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->errflg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_tell (hpgs_mem_istream_stream *stream, size_t *pos)
|
|
||||||
{
|
|
||||||
if (stream->errflg) return -1;
|
|
||||||
*pos = stream->gptr - stream->data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_seek (hpgs_mem_istream_stream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
if (stream->data + pos > stream->eptr)
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->gptr = stream->data+pos;
|
|
||||||
stream->errflg = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_seekend (hpgs_mem_istream_stream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
if (stream->data + pos > stream->eptr)
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->gptr = stream->eptr-pos;
|
|
||||||
stream->errflg = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t mem_read (void *ptr, size_t size, size_t nmemb, hpgs_mem_istream_stream *stream)
|
|
||||||
{
|
|
||||||
size_t ret = 0;
|
|
||||||
|
|
||||||
if (!stream->errflg)
|
|
||||||
{
|
|
||||||
if (stream->gptr < stream->eptr)
|
|
||||||
{
|
|
||||||
ret = (stream->eptr - stream->gptr)/size;
|
|
||||||
if (ret > nmemb) ret = nmemb;
|
|
||||||
|
|
||||||
memcpy(ptr,stream->gptr,size * ret);
|
|
||||||
stream->gptr += size * ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_istream_vtable mem_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_istream_getc_func_t) mem_getc,
|
|
||||||
(hpgs_istream_ungetc_func_t) mem_ungetc,
|
|
||||||
(hpgs_istream_close_func_t) mem_close,
|
|
||||||
(hpgs_istream_iseof_func_t) mem_iseof,
|
|
||||||
(hpgs_istream_iserror_func_t) mem_iserror,
|
|
||||||
(hpgs_istream_seek_func_t) mem_seek,
|
|
||||||
(hpgs_istream_tell_func_t) mem_tell,
|
|
||||||
(hpgs_istream_read_func_t) mem_read,
|
|
||||||
(hpgs_istream_seekend_func_t) mem_seekend
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Returns a new \c hpgs_istream created on the heap,
|
|
||||||
which operates on a chunk of memory in the given
|
|
||||||
location with the given size.
|
|
||||||
|
|
||||||
Returns a null pointer, when the system is out of memory.
|
|
||||||
*/
|
|
||||||
hpgs_istream *hpgs_new_mem_istream(const unsigned char *data,
|
|
||||||
size_t data_size,
|
|
||||||
hpgs_bool dup)
|
|
||||||
{
|
|
||||||
#define HPGS_ISTREAM_PAD_SZ (8*((sizeof(hpgs_istream)+7)/8))
|
|
||||||
#define HPGS_ISTREAM_STREAM_PAD_SZ (8*((sizeof(hpgs_mem_istream_stream)+7)/8))
|
|
||||||
|
|
||||||
hpgs_mem_istream_stream *stream;
|
|
||||||
hpgs_istream *ret;
|
|
||||||
size_t sz = HPGS_ISTREAM_PAD_SZ + HPGS_ISTREAM_STREAM_PAD_SZ;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
if (dup) sz += data_size;
|
|
||||||
|
|
||||||
ptr = malloc(sz);
|
|
||||||
ret = (hpgs_istream *)ptr;
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stream = (hpgs_mem_istream_stream *)(ptr+HPGS_ISTREAM_PAD_SZ);
|
|
||||||
|
|
||||||
if (dup)
|
|
||||||
{
|
|
||||||
unsigned char *ddata =
|
|
||||||
(unsigned char *)ptr + HPGS_ISTREAM_PAD_SZ + HPGS_ISTREAM_STREAM_PAD_SZ;
|
|
||||||
|
|
||||||
stream->data = ddata;
|
|
||||||
stream->gptr = ddata;
|
|
||||||
stream->eptr = ddata+data_size;
|
|
||||||
|
|
||||||
memcpy(ddata,data,data_size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream->data = data;
|
|
||||||
stream->gptr = data;
|
|
||||||
stream->eptr = data+data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->errflg = 0;
|
|
||||||
|
|
||||||
ret->stream = stream;
|
|
||||||
ret->vtable = &mem_vtable;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,263 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgslabel.c 381 2007-02-20 09:06:38Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of old-style HPGL labels. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <iconv.h>
|
|
||||||
#if defined ( __MINGW32__ ) || defined ( _MSC_VER )
|
|
||||||
#include<malloc.h>
|
|
||||||
#else
|
|
||||||
#include<alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HPGS_LABEL_NFACES 4
|
|
||||||
#define HPGS_LABEL_NENC 27
|
|
||||||
|
|
||||||
typedef struct hpgs_ttf_face_info_st hpgs_ttf_face_info;
|
|
||||||
|
|
||||||
struct hpgs_ttf_face_info_st
|
|
||||||
{
|
|
||||||
const char *font_name;
|
|
||||||
double x_fac;
|
|
||||||
double y_fac;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#define HPGS_LABEL_UCS_TYPE unsigned
|
|
||||||
#define HPGS_LABEL_UCS_ENC "UCS-4-INTERNAL"
|
|
||||||
#else
|
|
||||||
#define HPGS_LABEL_UCS_TYPE wchar_t
|
|
||||||
#define HPGS_LABEL_UCS_ENC "WCHAR_T"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static hpgs_ttf_face_info face_infos[HPGS_LABEL_NFACES] =
|
|
||||||
{
|
|
||||||
{ "LetterGothic", 1.48, 1.295 },
|
|
||||||
{ "LetterGothic Italic", 1.48, 1.295 },
|
|
||||||
{ "LetterGothic Bold", 1.48, 1.295 },
|
|
||||||
{ "LetterGothic Bold Italic", 1.48, 1.295 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *encoding_names[HPGS_LABEL_NENC] =
|
|
||||||
{
|
|
||||||
"HP-ROMAN8",
|
|
||||||
"LATIN1", // 14
|
|
||||||
"LATIN2", // 78
|
|
||||||
"LATIN5", // 174
|
|
||||||
"GREEK8", // 263
|
|
||||||
"CSISO25FRENCH", // 6
|
|
||||||
"CSISO69FRENCH", // 38
|
|
||||||
"CSISO14JISC6220RO", // 11
|
|
||||||
"CSISO11SWEDISHFORNAMES", // 19
|
|
||||||
"CSISO10SWEDISH", // 115
|
|
||||||
"CSISO60NORWEGIAN1", // 4
|
|
||||||
"CSISO61NORWEGIAN2", // 36
|
|
||||||
"CSISO21GERMAN", // 39
|
|
||||||
"CSISO15ITALIAN", // 9
|
|
||||||
"CSISO17SPANISH", // 83
|
|
||||||
"CSISO85SPANISH2", // 211
|
|
||||||
"CSISO16PORTUGESE", // 147
|
|
||||||
"CSISO84PORTUGESE2", // 179
|
|
||||||
"HEBREW", // 8,264
|
|
||||||
"CYRILLIC", // 18, 50
|
|
||||||
"ECMA-CYRILLIC", // 334
|
|
||||||
"MS-MAC-CYRILLIC", // 114
|
|
||||||
"WINDOWS-1252", // 309
|
|
||||||
"CP850", // 405
|
|
||||||
"CP852", // 565
|
|
||||||
"ARABIC7", // 22
|
|
||||||
"ARABIC" // 278
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hpgs_device_label_internal(hpgs_device *dev,
|
|
||||||
hpgs_point *pos,
|
|
||||||
const char *str, int str_len,
|
|
||||||
int face,
|
|
||||||
iconv_t encoding,
|
|
||||||
const char* encoding_name,
|
|
||||||
int posture,
|
|
||||||
int weight,
|
|
||||||
const hpgs_point *left_vec,
|
|
||||||
const hpgs_point *up_vec,
|
|
||||||
const hpgs_point *space_vec)
|
|
||||||
{
|
|
||||||
int iface = 0;
|
|
||||||
size_t i,len,inbytesleft;
|
|
||||||
HPGS_LABEL_UCS_TYPE ucs_str[HPGS_MAX_LABEL_SIZE];
|
|
||||||
size_t outbytesleft;
|
|
||||||
char *inbuf;
|
|
||||||
char *outbuf;
|
|
||||||
|
|
||||||
// get the face index.
|
|
||||||
if (posture)
|
|
||||||
iface += 1;
|
|
||||||
|
|
||||||
if (weight >= 3)
|
|
||||||
iface += 2;
|
|
||||||
|
|
||||||
// open the face.
|
|
||||||
hpgs_font *font = hpgs_find_font(face_infos[iface].font_name);
|
|
||||||
|
|
||||||
if (!font) return -1;
|
|
||||||
|
|
||||||
// convert to UNICODE
|
|
||||||
if (str_len > HPGS_MAX_LABEL_SIZE) str_len=HPGS_MAX_LABEL_SIZE;
|
|
||||||
inbytesleft = str_len;
|
|
||||||
outbytesleft = str_len*sizeof(HPGS_LABEL_UCS_TYPE);
|
|
||||||
inbuf = hpgs_alloca(str_len);
|
|
||||||
|
|
||||||
if (!inbuf)
|
|
||||||
return hpgs_set_error(hpgs_i18n("unable to allocate %d bytes of temporary string data."),
|
|
||||||
str_len);
|
|
||||||
memcpy(inbuf,str,str_len);
|
|
||||||
|
|
||||||
outbuf = (char*)ucs_str;
|
|
||||||
|
|
||||||
len=
|
|
||||||
iconv(encoding,&inbuf,&inbytesleft,&outbuf,&outbytesleft);
|
|
||||||
|
|
||||||
if (len == (size_t)(-1))
|
|
||||||
return hpgs_set_error(hpgs_i18n("unable to convert string to encoding %s: %s."),
|
|
||||||
encoding_name,strerror(errno));
|
|
||||||
|
|
||||||
len = (str_len*sizeof(HPGS_LABEL_UCS_TYPE) - outbytesleft) / sizeof(HPGS_LABEL_UCS_TYPE);
|
|
||||||
|
|
||||||
// OK, now let's go.
|
|
||||||
hpgs_matrix m;
|
|
||||||
|
|
||||||
m.mxx = left_vec->x * face_infos[iface].x_fac;
|
|
||||||
m.mxy = up_vec->x * face_infos[iface].y_fac;
|
|
||||||
m.myx = left_vec->y * face_infos[iface].x_fac;
|
|
||||||
m.myy = up_vec->y * face_infos[iface].y_fac;
|
|
||||||
|
|
||||||
for (i=0;i<len;i++)
|
|
||||||
{
|
|
||||||
m.dx = pos->x;
|
|
||||||
m.dy = pos->y;
|
|
||||||
|
|
||||||
unsigned gid = hpgs_font_get_glyph_id(font,(int)ucs_str[i]);
|
|
||||||
|
|
||||||
if (hpgs_font_draw_glyph(font,dev,&m,gid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
pos->x += space_vec->x;
|
|
||||||
pos->y += space_vec->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_reader_label(hpgs_reader *reader,
|
|
||||||
const char *str, int str_len,
|
|
||||||
int face,
|
|
||||||
int encoding,
|
|
||||||
int posture,
|
|
||||||
int weight,
|
|
||||||
const hpgs_point *left_vec,
|
|
||||||
const hpgs_point *up_vec,
|
|
||||||
const hpgs_point *space_vec)
|
|
||||||
{
|
|
||||||
int ienc;
|
|
||||||
|
|
||||||
// open the encoding.
|
|
||||||
switch (encoding)
|
|
||||||
{
|
|
||||||
case 14: ienc = 1; break;
|
|
||||||
case 78: ienc = 2; break;
|
|
||||||
case 174: ienc = 3; break;
|
|
||||||
case 263: ienc = 4; break;
|
|
||||||
case 6: ienc = 5; break;
|
|
||||||
case 38: ienc = 6; break;
|
|
||||||
case 11: ienc = 7; break;
|
|
||||||
case 19: ienc = 8; break;
|
|
||||||
case 115: ienc = 9; break;
|
|
||||||
case 4: ienc = 10; break;
|
|
||||||
case 36: ienc = 11; break;
|
|
||||||
case 39: ienc = 12; break;
|
|
||||||
case 9: ienc = 13; break;
|
|
||||||
case 83: ienc = 14; break;
|
|
||||||
case 211: ienc = 15; break;
|
|
||||||
case 147: ienc = 16; break;
|
|
||||||
case 179: ienc = 17; break;
|
|
||||||
case 8: case 264: ienc = 18; break;
|
|
||||||
case 18: case 50: ienc = 19; break;
|
|
||||||
case 334: ienc = 20; break;
|
|
||||||
case 114: ienc = 21; break;
|
|
||||||
case 309: ienc = 22; break;
|
|
||||||
case 405: ienc = 23; break;
|
|
||||||
case 565: ienc = 24; break;
|
|
||||||
case 22: ienc = 25; break;
|
|
||||||
case 278: ienc = 26; break;
|
|
||||||
default: ienc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
iconv_t ic = iconv_open(HPGS_LABEL_UCS_ENC,encoding_names[ienc]);
|
|
||||||
|
|
||||||
if (ic == (iconv_t)(-1))
|
|
||||||
return hpgs_set_error(hpgs_i18n("unable to open encoding %s."),
|
|
||||||
encoding_names[ienc]);
|
|
||||||
|
|
||||||
int ret =hpgs_device_label_internal(reader->device,&reader->current_point,
|
|
||||||
str,str_len,face,
|
|
||||||
ic,encoding_names[ienc],
|
|
||||||
posture,weight,left_vec,up_vec,space_vec);
|
|
||||||
|
|
||||||
iconv_close(ic);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_device_label(hpgs_device *dev,
|
|
||||||
hpgs_point *pos,
|
|
||||||
const char *str, int str_len,
|
|
||||||
int face,
|
|
||||||
const char *encoding,
|
|
||||||
int posture,
|
|
||||||
int weight,
|
|
||||||
const hpgs_point *left_vec,
|
|
||||||
const hpgs_point *up_vec,
|
|
||||||
const hpgs_point *space_vec)
|
|
||||||
{
|
|
||||||
// open the encoding.
|
|
||||||
iconv_t ic = iconv_open(HPGS_LABEL_UCS_ENC,encoding);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (ic == (iconv_t)(-1))
|
|
||||||
return hpgs_set_error(hpgs_i18n("unable to open encoding %s."),encoding);
|
|
||||||
|
|
||||||
ret = hpgs_device_label_internal(dev,pos,str,str_len,face,
|
|
||||||
ic,encoding,
|
|
||||||
posture,weight,left_vec,up_vec,space_vec);
|
|
||||||
iconv_close(ic);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,353 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgslexer.c 298 2006-03-05 18:18:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
int hpgs_reader_check_param_end(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isspace(reader->last_byte));
|
|
||||||
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
|
|
||||||
if (reader->last_byte == ';')
|
|
||||||
{
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
reader->eoc = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (reader->last_byte == ',')
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isspace(reader->last_byte));
|
|
||||||
|
|
||||||
if (isalpha(reader->last_byte) || reader->last_byte == HPGS_ESC)
|
|
||||||
{
|
|
||||||
reader->bytes_ignored = 1;
|
|
||||||
reader->eoc = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
reader->eoc = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader->last_byte == '"' || reader->last_byte == '\'' ||
|
|
||||||
isdigit(reader->last_byte) ||
|
|
||||||
reader->last_byte == '+' || reader->last_byte == '-' ||
|
|
||||||
reader->last_byte == '.')
|
|
||||||
{
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
reader->eoc = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (isalpha(reader->last_byte) || reader->last_byte == HPGS_ESC)
|
|
||||||
{
|
|
||||||
reader->bytes_ignored = 1;
|
|
||||||
reader->eoc = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read an integer argument from the stream - PCL version
|
|
||||||
return values: -1... read error/EOF
|
|
||||||
0... no integer found.
|
|
||||||
1... integer found.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_read_pcl_int(hpgs_reader *reader, int *x, int *sign)
|
|
||||||
{
|
|
||||||
*sign = 0;
|
|
||||||
*x=0;
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (reader->last_byte == '-')
|
|
||||||
{ *sign = -1; reader->last_byte=hpgs_getc(reader->in); }
|
|
||||||
else if (reader->last_byte == '+')
|
|
||||||
{ *sign = 1; reader->last_byte=hpgs_getc(reader->in); }
|
|
||||||
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!isdigit(reader->last_byte))
|
|
||||||
{ hpgs_ungetc(reader->last_byte,reader->in); return 0; }
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
*x = 10 * (*x) + (reader->last_byte-'0');
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isdigit(reader->last_byte));
|
|
||||||
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
if (*sign < 0)
|
|
||||||
*x = -*x;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read an integer argument from the stream
|
|
||||||
return values: -1... read error/EOF
|
|
||||||
0... success.
|
|
||||||
1... End of command.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_read_int(hpgs_reader *reader, int *x)
|
|
||||||
{
|
|
||||||
int sign = 0;
|
|
||||||
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
*x=0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isspace(reader->last_byte) || reader->last_byte==',');
|
|
||||||
|
|
||||||
if (reader->last_byte == '-')
|
|
||||||
sign = 1;
|
|
||||||
else if (reader->last_byte == '+')
|
|
||||||
sign = 0;
|
|
||||||
else if (isdigit(reader->last_byte))
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (isdigit(reader->last_byte))
|
|
||||||
*x = 10 * (*x) + (reader->last_byte-'0');
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
|
|
||||||
return hpgs_reader_check_param_end(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read a double argument from the stream
|
|
||||||
return values: -1... read error/EOF
|
|
||||||
0... success.
|
|
||||||
1... End of command.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_read_double(hpgs_reader *reader, double *x)
|
|
||||||
{
|
|
||||||
int sign = 0;
|
|
||||||
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
*x=0.0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isspace(reader->last_byte) || reader->last_byte==',');
|
|
||||||
|
|
||||||
if (reader->last_byte == '-')
|
|
||||||
sign = 1;
|
|
||||||
else if (reader->last_byte == '+')
|
|
||||||
sign = 0;
|
|
||||||
else if (!isdigit(reader->last_byte) && reader->last_byte != '.')
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (isdigit(reader->last_byte))
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
|
|
||||||
if (reader->last_byte != '.')
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (isdigit(reader->last_byte))
|
|
||||||
*x = 10.0 * (*x) + (reader->last_byte-'0');
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->last_byte == '.')
|
|
||||||
{
|
|
||||||
double xx=1.0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
xx *= 0.1;
|
|
||||||
|
|
||||||
if (isdigit(reader->last_byte))
|
|
||||||
*x += xx * (reader->last_byte-'0');
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
|
|
||||||
if (sign) *x = -*x;
|
|
||||||
|
|
||||||
return hpgs_reader_check_param_end(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_reader_read_point(hpgs_reader *reader, hpgs_point *p, int xform)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&p->x)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&p->y)) return -1;
|
|
||||||
|
|
||||||
switch (xform)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
hpgs_matrix_xform (p,&reader->total_matrix,p);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
hpgs_matrix_scale (p,&reader->total_matrix,p);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read an integer argument from the stream
|
|
||||||
return values: -1... read error/EOF
|
|
||||||
0... success.
|
|
||||||
1... End of command.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_read_new_string(hpgs_reader *reader, char *str)
|
|
||||||
{
|
|
||||||
int term=',';
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
while (isspace(reader->last_byte));
|
|
||||||
|
|
||||||
if (reader->last_byte == '\'' || reader->last_byte=='"')
|
|
||||||
term = reader->last_byte;
|
|
||||||
else
|
|
||||||
str[i++] = reader->last_byte;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (i<HPGS_MAX_LABEL_SIZE)
|
|
||||||
str[i] = reader->last_byte;
|
|
||||||
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (term == ',' && reader->last_byte == ';') break;
|
|
||||||
}
|
|
||||||
while (reader->last_byte != term);
|
|
||||||
|
|
||||||
if (i) --i;
|
|
||||||
str[i] = '\0';
|
|
||||||
|
|
||||||
return hpgs_reader_check_param_end(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_reader_read_label_string(hpgs_reader *reader, char *str)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (reader->last_byte == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (i<HPGS_MAX_LABEL_SIZE)
|
|
||||||
str[i] = reader->last_byte;
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
while (reader->last_byte != reader->label_term);
|
|
||||||
|
|
||||||
if (reader->label_term_ignore && i)
|
|
||||||
--i;
|
|
||||||
|
|
||||||
str[i] = '\0';
|
|
||||||
|
|
||||||
return hpgs_reader_check_param_end(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsmatrix.c 298 2006-03-05 18:18:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the public API for transformation matrices. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the given matrix to the identity matrix.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_set_identity(hpgs_matrix *m)
|
|
||||||
{
|
|
||||||
m->myx = m->mxy = m->dy = m->dx = 0.0;
|
|
||||||
m->myy = m->mxx = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given point \c p with the matrix \c m.
|
|
||||||
The result is stored in \c res.
|
|
||||||
The pointers \c p and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_xform(hpgs_point *res,
|
|
||||||
const hpgs_matrix *m, const hpgs_point *p)
|
|
||||||
{
|
|
||||||
double x = m->dx + m->mxx * p->x + m->mxy * p->y;
|
|
||||||
double y = m->dy + m->myx * p->x + m->myy * p->y;
|
|
||||||
res->x = x;
|
|
||||||
res->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given point \c p with the inverse of the matrix \c m.
|
|
||||||
The result is stored in \c res.
|
|
||||||
The pointers \c p and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_ixform(hpgs_point *res,
|
|
||||||
const hpgs_point *p, const hpgs_matrix *m)
|
|
||||||
{
|
|
||||||
double x0 = (p->x - m->dx);
|
|
||||||
double y0 = (p->y - m->dy);
|
|
||||||
|
|
||||||
double det = m->mxx * m->myy - m->mxy * m->myx;
|
|
||||||
|
|
||||||
res->x = (m->myy * x0 - m->mxy * y0)/det;
|
|
||||||
res->y = (m->mxx * y0 - m->myx * x0)/det;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given bounding box \c bb with the matrix \c m.
|
|
||||||
The result is the enclosing bounding box of the transformed
|
|
||||||
rectangle of the bounding box and is stored in \c res.
|
|
||||||
The pointers \c bb and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_xform_bbox(hpgs_bbox *res,
|
|
||||||
const hpgs_matrix *m, const hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
hpgs_point ll = { bb->llx, bb->lly };
|
|
||||||
hpgs_point ur = { bb->urx, bb->ury };
|
|
||||||
|
|
||||||
hpgs_point lr = { bb->llx, bb->ury };
|
|
||||||
hpgs_point ul = { bb->urx, bb->lly };
|
|
||||||
|
|
||||||
hpgs_matrix_xform(&ll,m,&ll);
|
|
||||||
hpgs_matrix_xform(&ur,m,&ur);
|
|
||||||
|
|
||||||
hpgs_matrix_xform(&lr,m,&lr);
|
|
||||||
hpgs_matrix_xform(&ul,m,&ul);
|
|
||||||
|
|
||||||
res->llx = HPGS_MIN(HPGS_MIN(ll.x,ur.x),HPGS_MIN(lr.x,ul.x));
|
|
||||||
res->lly = HPGS_MIN(HPGS_MIN(ll.y,ur.y),HPGS_MIN(lr.y,ul.y));
|
|
||||||
|
|
||||||
res->urx = HPGS_MAX(HPGS_MAX(ll.x,ur.x),HPGS_MAX(lr.x,ul.x));
|
|
||||||
res->ury = HPGS_MAX(HPGS_MAX(ll.y,ur.y),HPGS_MAX(lr.y,ul.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given bounding box \c bb with the the inverse of
|
|
||||||
the matrix \c m.
|
|
||||||
The result is the enclosing bounding box of the transformed
|
|
||||||
rectangle of the bounding box and is stored in \c res.
|
|
||||||
The pointers \c bb and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_ixform_bbox(hpgs_bbox *res,
|
|
||||||
const hpgs_bbox *bb, const hpgs_matrix *m)
|
|
||||||
{
|
|
||||||
hpgs_point ll = { bb->llx, bb->lly };
|
|
||||||
hpgs_point ur = { bb->urx, bb->ury };
|
|
||||||
|
|
||||||
hpgs_point lr = { bb->llx, bb->ury };
|
|
||||||
hpgs_point ul = { bb->urx, bb->lly };
|
|
||||||
|
|
||||||
hpgs_matrix_ixform(&ll,&ll,m);
|
|
||||||
hpgs_matrix_ixform(&ur,&ur,m);
|
|
||||||
|
|
||||||
hpgs_matrix_ixform(&lr,&lr,m);
|
|
||||||
hpgs_matrix_ixform(&ul,&ul,m);
|
|
||||||
|
|
||||||
res->llx = HPGS_MIN(HPGS_MIN(ll.x,ur.x),HPGS_MIN(lr.x,ul.x));
|
|
||||||
res->lly = HPGS_MIN(HPGS_MIN(ll.y,ur.y),HPGS_MIN(lr.y,ul.y));
|
|
||||||
|
|
||||||
res->urx = HPGS_MAX(HPGS_MAX(ll.x,ur.x),HPGS_MAX(lr.x,ul.x));
|
|
||||||
res->ury = HPGS_MAX(HPGS_MAX(ll.y,ur.y),HPGS_MAX(lr.y,ul.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given point \c p with the matrix \c m without
|
|
||||||
applying the translation part of \c m. This is useful in order
|
|
||||||
to transform delta vectors.
|
|
||||||
|
|
||||||
The result is stored in \c res.
|
|
||||||
The pointers \c p and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_scale(hpgs_point *res,
|
|
||||||
const hpgs_matrix *m, const hpgs_point *p)
|
|
||||||
{
|
|
||||||
double x = m->mxx * p->x + m->mxy * p->y;
|
|
||||||
double y = m->myx * p->x + m->myy * p->y;
|
|
||||||
res->x = x;
|
|
||||||
res->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Transforms the given point \c p with the inverse of the matrix \c m
|
|
||||||
without applying the translation part of \c m. This is useful in order
|
|
||||||
to transform delta vectors.
|
|
||||||
|
|
||||||
The result is stored in \c res.
|
|
||||||
The pointers \c p and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_iscale(hpgs_point *res,
|
|
||||||
const hpgs_point *p, const hpgs_matrix *m)
|
|
||||||
{
|
|
||||||
double x0 = p->x;
|
|
||||||
double y0 = p->y;
|
|
||||||
|
|
||||||
double det = m->mxx * m->myy - m->mxy * m->myx;
|
|
||||||
|
|
||||||
res->x = (m->myy * x0 - m->mxy * y0)/det;
|
|
||||||
res->y = (m->mxx * y0 - m->myx * x0)/det;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Concatenates the given matrices \c a and \c b.
|
|
||||||
The result is stored in \c res.
|
|
||||||
Either of the pointer \c a or \b may point to the same memory location as
|
|
||||||
the pointer \c res.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_concat(hpgs_matrix *res,
|
|
||||||
const hpgs_matrix *a, const hpgs_matrix *b)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// | 1 0 0 | | 1 0 0 | | 1 0 0 |
|
|
||||||
// | dx mxx mxy | x | Dx Mxx Mxy | = | dx+Dx*mxx+Dy*mxy mxx*Mxx+mxy*Myx mxx*Mxy+mxy*Myy |
|
|
||||||
// | dy myx myy | | Dy Myx Myy | | dy+Dx*myx+Dy*myy myx*Mxx+myy*Myx myx*Mxy+myy*Myy |
|
|
||||||
//
|
|
||||||
double r0,r1,r2,r3;
|
|
||||||
|
|
||||||
r0 = a->dx+b->dx*a->mxx+b->dy*a->mxy;
|
|
||||||
r1 = a->dy+b->dx*a->myx+b->dy*a->myy;
|
|
||||||
|
|
||||||
res->dx = r0;
|
|
||||||
res->dy = r1;
|
|
||||||
|
|
||||||
r0 = a->mxx*b->mxx+a->mxy*b->myx;
|
|
||||||
r1 = a->mxx*b->mxy+a->mxy*b->myy;
|
|
||||||
r2 = a->myx*b->mxx+a->myy*b->myx;
|
|
||||||
r3 = a->myx*b->mxy+a->myy*b->myy;
|
|
||||||
|
|
||||||
res->mxx = r0;
|
|
||||||
res->mxy = r1;
|
|
||||||
res->myx = r2;
|
|
||||||
res->myy = r3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Inverts the given matrix \c m.
|
|
||||||
The result is stored in \c res.
|
|
||||||
The pointers \c m and \c res may point to the same memory location.
|
|
||||||
*/
|
|
||||||
void hpgs_matrix_invert(hpgs_matrix *res, const hpgs_matrix *m)
|
|
||||||
{
|
|
||||||
double det = m->mxx * m->myy - m->mxy * m->myx;
|
|
||||||
|
|
||||||
double tmp = m->mxx/det;
|
|
||||||
res->mxx = m->myy/det;
|
|
||||||
res->myy = tmp;
|
|
||||||
|
|
||||||
res->mxy = -m->mxy/det;
|
|
||||||
res->myx = -m->myx/det;
|
|
||||||
|
|
||||||
double x0 = -m->dx;
|
|
||||||
double y0 = -m->dy;
|
|
||||||
res->dx = x0 * res->mxx + y0 * res->mxy;
|
|
||||||
res->dy = x0 * res->myx + y0 * res->myy;
|
|
||||||
}
|
|
||||||
@@ -1,527 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsmkrop.c 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* A small programm, which generates the raster operations hpgsrop.c *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__attribute__((format(printf,4,5)))
|
|
||||||
#endif
|
|
||||||
static int apprintf (char *str, size_t str_sz, size_t *str_len,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
n = vsnprintf(str+*str_len,str_sz-*str_len,fmt,ap);
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (n<0) { perror("snprintf"); return -1; }
|
|
||||||
*str_len+=n;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mk_operand (char *operand, size_t operand_sz, const char *stack, int i)
|
|
||||||
{
|
|
||||||
switch (stack[i])
|
|
||||||
{
|
|
||||||
case 'D':
|
|
||||||
strcpy(operand,"*D");
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
operand[0] = stack[i];
|
|
||||||
operand[1] = '\0';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf(operand,operand_sz,"stk%d",i+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mk_xoperand (char *operand, size_t operand_sz, const char *stack, int i)
|
|
||||||
{
|
|
||||||
switch (stack[i])
|
|
||||||
{
|
|
||||||
case 'D':
|
|
||||||
strcpy(operand,"D");
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
operand[0] = stack[i];
|
|
||||||
operand[1] = '\0';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf(operand,operand_sz,"stk%d",i+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
This function converts a ROP3 description cf. to
|
|
||||||
|
|
||||||
PCL 5 Comparison Guide, Edition 2, 6/2003, Hewlett Packard
|
|
||||||
(May be downloaded as bpl13206.pdf from http://www.hp.com)
|
|
||||||
|
|
||||||
into 4 C-programs for all transparency modes supported by
|
|
||||||
HPGL/2 and PCL.
|
|
||||||
|
|
||||||
Additional information may be found under
|
|
||||||
|
|
||||||
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50grfTernaryRasterOperations.asp
|
|
||||||
|
|
||||||
(especially typos in HP's documentation are corrected from
|
|
||||||
this source of information).
|
|
||||||
|
|
||||||
*/
|
|
||||||
static int write_rop3_func(FILE *out, int irop, const char *ropstr)
|
|
||||||
{
|
|
||||||
int stacksz = 0;
|
|
||||||
int max_stacksz = 0;
|
|
||||||
char stack[32];
|
|
||||||
char operand[32];
|
|
||||||
char operand2[32];
|
|
||||||
const char *c;
|
|
||||||
|
|
||||||
int D_used = 0;
|
|
||||||
int S_used = 0;
|
|
||||||
int T_used = 0;
|
|
||||||
|
|
||||||
char defn[2048],op;
|
|
||||||
size_t defn_len=0;
|
|
||||||
char xdefn[2048];
|
|
||||||
size_t xdefn_len=0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
defn[0] = '\0';
|
|
||||||
xdefn[0] = '\0';
|
|
||||||
|
|
||||||
for (c=ropstr;*c;++c)
|
|
||||||
switch (*c)
|
|
||||||
{
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
i = (*c == '0') ? 0 : 255;
|
|
||||||
max_stacksz = stacksz = 1;
|
|
||||||
|
|
||||||
if (c!=ropstr || *(c+1))
|
|
||||||
{
|
|
||||||
fprintf (stderr,"Misplaced %c in rop string %s.\n",
|
|
||||||
*c,ropstr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apprintf(defn,sizeof(defn),&defn_len,
|
|
||||||
" stk1 = %d;\n",i ))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (apprintf(xdefn,sizeof(xdefn),&xdefn_len,
|
|
||||||
" stk1 = %s;\n", (*c == '0') ? "0x0000" : "0xffff"))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
case 'D':
|
|
||||||
if (stacksz >= sizeof(stack)-1)
|
|
||||||
{
|
|
||||||
fprintf (stderr,"Stack overflow in rop string %s.\n",ropstr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack[stacksz] = *c;
|
|
||||||
++stacksz;
|
|
||||||
|
|
||||||
if (*c == 'D')
|
|
||||||
D_used = 1;
|
|
||||||
|
|
||||||
if (*c == 'T')
|
|
||||||
T_used = 1;
|
|
||||||
|
|
||||||
if (*c == 'S')
|
|
||||||
S_used = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'o':
|
|
||||||
case 'a':
|
|
||||||
case 'x':
|
|
||||||
if (stacksz<1)
|
|
||||||
{
|
|
||||||
fprintf (stderr,"Stack underflow in rop string %s.\n",ropstr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mk_operand(operand,sizeof(operand),stack,stacksz-2);
|
|
||||||
mk_operand(operand2,sizeof(operand),stack,stacksz-1);
|
|
||||||
|
|
||||||
op = (*c == 'o') ? '|' : ((*c == 'a') ? '&' : '^');
|
|
||||||
|
|
||||||
if (apprintf(defn,sizeof(defn),&defn_len,
|
|
||||||
" stk%d = %s %c %s;\n",
|
|
||||||
stacksz-1,operand,op,operand2 ))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
mk_xoperand(operand,sizeof(operand),stack,stacksz-2);
|
|
||||||
mk_xoperand(operand2,sizeof(operand),stack,stacksz-1);
|
|
||||||
|
|
||||||
if (apprintf(xdefn,sizeof(xdefn),&xdefn_len,
|
|
||||||
" stk%d = %s %c %s;\n",
|
|
||||||
stacksz-1,operand,op,operand2 ))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
--stacksz;
|
|
||||||
// account for the max intermediate result on the stack.
|
|
||||||
if (stacksz > max_stacksz) max_stacksz = stacksz;
|
|
||||||
|
|
||||||
stack[stacksz-1] = '\0';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
mk_operand(operand,sizeof(operand),stack,stacksz-1);
|
|
||||||
|
|
||||||
if (apprintf(defn,sizeof(defn),&defn_len,
|
|
||||||
" stk%d = ~%s;\n",
|
|
||||||
stacksz,operand ))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
mk_xoperand(operand,sizeof(operand),stack,stacksz-1);
|
|
||||||
|
|
||||||
if (apprintf(xdefn,sizeof(xdefn),&xdefn_len,
|
|
||||||
" stk%d = ~%s;\n",
|
|
||||||
stacksz,operand ))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// account for the max intermediate result on the stack.
|
|
||||||
if (stacksz > max_stacksz) max_stacksz = stacksz;
|
|
||||||
|
|
||||||
stack[stacksz-1] = '\0';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf (stderr,"Illegal character %c in rop string %s.\n",
|
|
||||||
*c,ropstr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stacksz!=1)
|
|
||||||
{
|
|
||||||
fprintf (stderr,"Unbalanced shift/reduce in rop string %s.\n",ropstr);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mk_operand(operand,sizeof(operand),stack,0);
|
|
||||||
|
|
||||||
// ******** normal ROP functions
|
|
||||||
// case 1: source/pattern opaque.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source/pattern opaque. */\n"
|
|
||||||
"static void rop3_%d_0_0 (unsigned char *D, unsigned char S, unsigned char T)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned char stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(defn,out);
|
|
||||||
|
|
||||||
// optimize for noop.
|
|
||||||
if (stack[0] != 'D')
|
|
||||||
fprintf(out," *D = %s;\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 2: source opaque/pattern transparent.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source opaque/pattern transparent. */\n"
|
|
||||||
"static void rop3_%d_0_1 (unsigned char *D, unsigned char S, unsigned char T)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned char stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(defn,out);
|
|
||||||
|
|
||||||
// Image_A = Temporary_ROP3, & Not Src.
|
|
||||||
// Image_B = Temporary_ROP3 & Pattern.
|
|
||||||
// Image_C = Not Pattern & Src & Dest.
|
|
||||||
// Return Image_A | Image_B | Image_C
|
|
||||||
fprintf(out," *D = (%s & S) | (%s & (~T)) | (T & (~S) & *D);\n",operand,operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 3: source transparent/pattern opaque.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source transparent/pattern opaque. */\n"
|
|
||||||
"static void rop3_%d_1_0 (unsigned char *D, unsigned char S, unsigned char T)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned char stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(defn,out);
|
|
||||||
|
|
||||||
// Image_A = Temporary_ROP3 & Src.
|
|
||||||
// Image_B = Dest & Not Src.
|
|
||||||
// Return Image_A | Image_B
|
|
||||||
fprintf(out," *D = (%s & (~S)) | (*D & S);\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 4: source/pattern transparent.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source/pattern transparent. */\n"
|
|
||||||
"static void rop3_%d_1_1 (unsigned char *D, unsigned char S, unsigned char T)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned char stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(defn,out);
|
|
||||||
// Image_A = Temporary_ROP3 & Src & Pattern.
|
|
||||||
// Image_B = Dest & Not Src.
|
|
||||||
// Image_C = Dest & Not Pattern.
|
|
||||||
// Return Image_A | Image_B | Image_C.
|
|
||||||
fprintf(out," *D = (%s & (~S) & (~T)) | (*D & S) | (*D & T);\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// ******** ROP transfer functions
|
|
||||||
mk_xoperand(operand,sizeof(operand),stack,0);
|
|
||||||
// case 1: source/pattern opaque.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source/pattern opaque. */\n"
|
|
||||||
"static unsigned xrop3_%d_0_0 (unsigned char s, unsigned char t)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
if (D_used)
|
|
||||||
fprintf (out," unsigned D = 0x00ff;\n");
|
|
||||||
if (S_used)
|
|
||||||
fprintf (out," unsigned S = ((unsigned)s << 8) | s;\n");
|
|
||||||
if (T_used)
|
|
||||||
fprintf (out," unsigned T = ((unsigned)t << 8) | t;\n");
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(xdefn,out);
|
|
||||||
|
|
||||||
fprintf(out," return %s;\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 2: source opaque/pattern transparent.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source opaque/pattern transparent. */\n"
|
|
||||||
"static unsigned xrop3_%d_0_1 (unsigned char s, unsigned char t)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
fprintf (out," unsigned D = 0x00ff;\n");
|
|
||||||
fprintf (out," unsigned S = ((unsigned)s << 8) | s;\n");
|
|
||||||
fprintf (out," unsigned T = ((unsigned)t << 8) | t;\n");
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(xdefn,out);
|
|
||||||
|
|
||||||
// Image_A = Temporary_ROP3, & Not Src.
|
|
||||||
// Image_B = Temporary_ROP3 & Pattern.
|
|
||||||
// Image_C = Not Pattern & Src & Dest.
|
|
||||||
// Return Image_A | Image_B | Image_C
|
|
||||||
fprintf(out," return (%s & S) | (%s & (~T)) | (T & (~S) & D);\n",operand,operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 3: source transparent/pattern opaque.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source transparent/pattern opaque. */\n"
|
|
||||||
"static unsigned xrop3_%d_1_0 (unsigned char s, unsigned char t)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
fprintf (out," unsigned D = 0x00ff;\n");
|
|
||||||
fprintf (out," unsigned S = ((unsigned)s << 8) | s;\n");
|
|
||||||
if (T_used)
|
|
||||||
fprintf (out," unsigned T = ((unsigned)t << 8) | t;\n");
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(xdefn,out);
|
|
||||||
|
|
||||||
// Image_A = Temporary_ROP3 & Src.
|
|
||||||
// Image_B = Dest & Not Src.
|
|
||||||
// Return Image_A | Image_B
|
|
||||||
fprintf(out," return (%s & (~S)) | (D & S);\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
// case 4: source/pattern transparent.
|
|
||||||
fprintf (out,
|
|
||||||
"/* %s source/pattern transparent. */\n"
|
|
||||||
"static unsigned xrop3_%d_1_1 (unsigned char s, unsigned char t)\n{\n",
|
|
||||||
ropstr,irop);
|
|
||||||
|
|
||||||
fprintf (out," unsigned D = 0x00ff;\n");
|
|
||||||
fprintf (out," unsigned S = ((unsigned)s << 8) | s;\n");
|
|
||||||
fprintf (out," unsigned T = ((unsigned)t << 8) | t;\n");
|
|
||||||
|
|
||||||
for (i=1;i<=max_stacksz;++i)
|
|
||||||
fprintf(out," unsigned stk%d;\n",i);
|
|
||||||
|
|
||||||
fputs(xdefn,out);
|
|
||||||
// Image_A = Temporary_ROP3 & Src & Pattern.
|
|
||||||
// Image_B = Dest & Not Src.
|
|
||||||
// Image_C = Dest & Not Pattern.
|
|
||||||
// Return Image_A | Image_B | Image_C.
|
|
||||||
fprintf(out," return (%s & (~S) & (~T)) | (D & S) | (D & T);\n",operand);
|
|
||||||
|
|
||||||
fprintf(out,"}\n\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
FILE *in=0;
|
|
||||||
FILE *out=0;
|
|
||||||
int irop=0,i;
|
|
||||||
char ropstr[32];
|
|
||||||
int ret = 0;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
if (argc != 3)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"usage: %s <in> <out>.\n",argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
in = fopen(argv[1],"rb");
|
|
||||||
|
|
||||||
if (!in)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: Error opening file <%s>: %s.\n",
|
|
||||||
argv[0],argv[1],strerror(errno));
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
out = fopen(argv[2],"wb");
|
|
||||||
|
|
||||||
if (!out)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: Error opening file <%s>: %s.\n",
|
|
||||||
argv[0],argv[2],strerror(errno));
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
now = time(0);
|
|
||||||
fprintf(out,"/* Generated automatically by %s at %.24s.\n",argv[0],ctime(&now));
|
|
||||||
fprintf(out," Do not edit!\n");
|
|
||||||
fprintf(out," */\n");
|
|
||||||
fprintf(out,"#include <hpgs.h>\n\n");
|
|
||||||
|
|
||||||
|
|
||||||
// go through all ROP descritions in hpgsrop.dat
|
|
||||||
while (fscanf(in,"%d %31s",&i,ropstr) == 2)
|
|
||||||
{
|
|
||||||
if (i!=irop)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"%s: Illegal count %d in stanza %d.\n",
|
|
||||||
argv[0],i,irop);
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write_rop3_func(out,irop,ropstr))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
++irop;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect all rop function in one big lookup table...
|
|
||||||
fprintf(out,
|
|
||||||
"static hpgs_rop3_func_t rop3_table[][2][2] = {\n");
|
|
||||||
|
|
||||||
for (i=0;i<irop;++i)
|
|
||||||
fprintf(out,
|
|
||||||
" {{rop3_%d_0_0,rop3_%d_0_1},{rop3_%d_1_0,rop3_%d_1_1}}%s\n",
|
|
||||||
i,i,i,i,i<irop-1 ? "," : "");
|
|
||||||
|
|
||||||
fprintf(out,
|
|
||||||
"};\n\n");
|
|
||||||
|
|
||||||
// generate our public interface hpgs_rop3_func.
|
|
||||||
fprintf(out,
|
|
||||||
"hpgs_rop3_func_t hpgs_rop3_func(int rop3,\n"
|
|
||||||
" hpgs_bool src_transparency,\n"
|
|
||||||
" hpgs_bool pattern_transparency)\n"
|
|
||||||
"{\n"
|
|
||||||
" if (rop3 < 0 || rop3 >= %d) return 0;\n"
|
|
||||||
" return rop3_table[rop3][src_transparency!=0][pattern_transparency!=0];\n"
|
|
||||||
"}\n",
|
|
||||||
irop);
|
|
||||||
|
|
||||||
// Collect all rop xfer function in one big lookup table...
|
|
||||||
fprintf(out,
|
|
||||||
"static hpgs_xrop3_func_t xrop3_table[][2][2] = {\n");
|
|
||||||
|
|
||||||
for (i=0;i<irop;++i)
|
|
||||||
fprintf(out,
|
|
||||||
" {{xrop3_%d_0_0,xrop3_%d_0_1},{xrop3_%d_1_0,xrop3_%d_1_1}}%s\n",
|
|
||||||
i,i,i,i,i<irop-1 ? "," : "");
|
|
||||||
|
|
||||||
fprintf(out,
|
|
||||||
"};\n\n");
|
|
||||||
|
|
||||||
// generate our public interface hpgs_xrop3_func.
|
|
||||||
fprintf(out,
|
|
||||||
"hpgs_xrop3_func_t hpgs_xrop3_func(int rop3,\n"
|
|
||||||
" hpgs_bool src_transparency,\n"
|
|
||||||
" hpgs_bool pattern_transparency)\n"
|
|
||||||
"{\n"
|
|
||||||
" if (rop3 < 0 || rop3 >= %d) return 0;\n"
|
|
||||||
" return xrop3_table[rop3][src_transparency!=0][pattern_transparency!=0];\n"
|
|
||||||
"}\n",
|
|
||||||
irop);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (in) fclose(in);
|
|
||||||
if (out) fclose(out);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsmutex.h 286 2006-03-03 15:14:14Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private header file for thread mutex support. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_MUTEX_H__
|
|
||||||
#define __HPGS_MUTEX_H__
|
|
||||||
|
|
||||||
#ifndef __HPGS_H
|
|
||||||
#include <hpgs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
typedef CRITICAL_SECTION hpgs_mutex_t;
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
typedef pthread_mutex_t hpgs_mutex_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void hpgs_mutex_init(hpgs_mutex_t *m);
|
|
||||||
static void hpgs_mutex_destroy(hpgs_mutex_t *m);
|
|
||||||
static void hpgs_mutex_lock(hpgs_mutex_t *m);
|
|
||||||
static void hpgs_mutex_unlock(hpgs_mutex_t *m);
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_init(hpgs_mutex_t *m)
|
|
||||||
{ InitializeCriticalSection(m); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_destroy(hpgs_mutex_t *m)
|
|
||||||
{ DeleteCriticalSection(m); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_lock(hpgs_mutex_t *m)
|
|
||||||
{ EnterCriticalSection(m); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_unlock(hpgs_mutex_t *m)
|
|
||||||
{ LeaveCriticalSection(m); }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_init(hpgs_mutex_t *m)
|
|
||||||
{ pthread_mutex_init(m,0); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_destroy(hpgs_mutex_t *m)
|
|
||||||
{ pthread_mutex_destroy(m); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_lock(hpgs_mutex_t *m)
|
|
||||||
{ pthread_mutex_lock(m); }
|
|
||||||
|
|
||||||
__inline__ void hpgs_mutex_unlock(hpgs_mutex_t *m)
|
|
||||||
{ pthread_mutex_unlock(m); }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,343 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsostream.c 368 2006-12-31 15:18:08Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of basic output streams. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
#include<string.h>
|
|
||||||
#include<stdarg.h>
|
|
||||||
|
|
||||||
/*! The counterpart of ANSI fprintf for \c hpgs_ostream. */
|
|
||||||
int hpgs_ostream_printf (hpgs_ostream *_this, const char *msg, ...)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap,msg);
|
|
||||||
ret=_this->vtable->vprintf_func(_this->stream,msg,ap);
|
|
||||||
va_end(ap);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! The counterpart of ANSI fvprintf for \c hpgs_ostream. */
|
|
||||||
int hpgs_ostream_vprintf (hpgs_ostream *_this, const char *msg, va_list ap)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
ret = _this->vtable->vprintf_func(_this->stream,msg,aq);
|
|
||||||
va_end(aq);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int file_seek (FILE *file, size_t pos)
|
|
||||||
{
|
|
||||||
return fseek(file,pos,SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int file_tell (FILE *file, int layer, size_t *pos)
|
|
||||||
{
|
|
||||||
if (layer) return -1;
|
|
||||||
|
|
||||||
long pp=ftell(file);
|
|
||||||
|
|
||||||
if (pp<0) return -1;
|
|
||||||
|
|
||||||
*pos = pp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_ostream_vtable stdfile_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_ostream_putc_func_t) putc,
|
|
||||||
(hpgs_ostream_write_func_t) fwrite,
|
|
||||||
(hpgs_ostream_vprintf_func_t) vfprintf,
|
|
||||||
(hpgs_ostream_flush_func_t) fflush,
|
|
||||||
(hpgs_ostream_close_func_t) fflush,
|
|
||||||
(hpgs_ostream_iserror_func_t) ferror,
|
|
||||||
(hpgs_ostream_getbuf_func_t) 0,
|
|
||||||
(hpgs_ostream_tell_func_t) file_tell,
|
|
||||||
(hpgs_ostream_seek_func_t) 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static hpgs_ostream_vtable file_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_ostream_putc_func_t) putc,
|
|
||||||
(hpgs_ostream_write_func_t) fwrite,
|
|
||||||
(hpgs_ostream_vprintf_func_t) vfprintf,
|
|
||||||
(hpgs_ostream_flush_func_t) fflush,
|
|
||||||
(hpgs_ostream_close_func_t) fclose,
|
|
||||||
(hpgs_ostream_iserror_func_t) ferror,
|
|
||||||
(hpgs_ostream_getbuf_func_t) 0,
|
|
||||||
(hpgs_ostream_tell_func_t) file_tell,
|
|
||||||
(hpgs_ostream_seek_func_t) file_seek
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Returns a new \c hpgs_ostream created on the heap,
|
|
||||||
which operates on a file, which is opened by this call
|
|
||||||
in write-only mode.
|
|
||||||
|
|
||||||
Returns a null pointer, when an I/O error occurrs.
|
|
||||||
In this case, details about the the error can be retrieved
|
|
||||||
using \c errno.
|
|
||||||
*/
|
|
||||||
hpgs_ostream *hpgs_new_file_ostream (const char *fn)
|
|
||||||
{
|
|
||||||
FILE *out = fn ? fopen (fn,"wb") : stdout;
|
|
||||||
hpgs_ostream *ret = 0;
|
|
||||||
|
|
||||||
if (!out) return 0;
|
|
||||||
|
|
||||||
ret = (hpgs_ostream *)malloc(sizeof(hpgs_ostream));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
fclose(out);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->stream = out;
|
|
||||||
|
|
||||||
if (fn)
|
|
||||||
ret->vtable = &file_vtable;
|
|
||||||
else
|
|
||||||
ret->vtable = &stdfile_vtable;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct hpgs_mem_ostream_stream_st hpgs_mem_ostream_stream;
|
|
||||||
|
|
||||||
struct hpgs_mem_ostream_stream_st
|
|
||||||
{
|
|
||||||
unsigned char *data;
|
|
||||||
unsigned char *pptr;
|
|
||||||
unsigned char *eptr;
|
|
||||||
int errflg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mem_grow (hpgs_mem_ostream_stream *stream, size_t hint)
|
|
||||||
{
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
size_t pos = stream->pptr-stream->data;
|
|
||||||
size_t sz = stream->eptr-stream->data;
|
|
||||||
size_t sz2 = (hint > sz) ? sz+hint : 2*sz;
|
|
||||||
|
|
||||||
// check for overflow.
|
|
||||||
if (sz2 < sz)
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *ndata=(unsigned char *)realloc(stream->data,sz2);
|
|
||||||
|
|
||||||
if (ndata)
|
|
||||||
{
|
|
||||||
stream->data=ndata;
|
|
||||||
stream->pptr=stream->data+pos;
|
|
||||||
stream->eptr=stream->data+sz2;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_putc (int c, hpgs_mem_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->pptr >= stream->eptr)
|
|
||||||
mem_grow(stream,0);
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
*stream->pptr = c;
|
|
||||||
++stream->pptr;
|
|
||||||
|
|
||||||
return c & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t mem_write (void *ptr, size_t size, size_t nmemb, hpgs_mem_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->pptr + size*nmemb > stream->eptr)
|
|
||||||
mem_grow(stream,size*nmemb);
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memcpy(stream->pptr,ptr,size*nmemb);
|
|
||||||
stream->pptr += size*nmemb;
|
|
||||||
|
|
||||||
return nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_vprintf (hpgs_mem_ostream_stream *stream, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
size = stream->eptr - stream->pptr;
|
|
||||||
/* Try to print in the allocated space. */
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
#ifdef WIN32
|
|
||||||
n = _vsnprintf (stream->pptr, size, fmt, aq);
|
|
||||||
#else
|
|
||||||
n = vsnprintf ((char*)stream->pptr, size, fmt, aq);
|
|
||||||
#endif
|
|
||||||
va_end(aq);
|
|
||||||
/* If that worked, return the string. */
|
|
||||||
if (n > -1 && n < size)
|
|
||||||
{
|
|
||||||
stream->pptr += n;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Else try again with more space. */
|
|
||||||
mem_grow(stream,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_close (hpgs_mem_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->data) free(stream->data);
|
|
||||||
free(stream);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_iserror (hpgs_mem_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->errflg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_istream *mem_getbuf (hpgs_mem_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->errflg || !stream->data)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return hpgs_new_mem_istream (stream->data,stream->pptr-stream->data,HPGS_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_tell (hpgs_mem_ostream_stream *stream, int layer, size_t *pos)
|
|
||||||
{
|
|
||||||
if (layer || stream->errflg) return -1;
|
|
||||||
|
|
||||||
*pos = stream->pptr-stream->data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mem_seek (hpgs_mem_ostream_stream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
if (stream->errflg) return -1;
|
|
||||||
|
|
||||||
if (stream->data + pos > stream->pptr)
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->pptr = stream->data + pos;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_ostream_vtable mem_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_ostream_putc_func_t) mem_putc,
|
|
||||||
(hpgs_ostream_write_func_t) mem_write,
|
|
||||||
(hpgs_ostream_vprintf_func_t) mem_vprintf,
|
|
||||||
(hpgs_ostream_flush_func_t) 0,
|
|
||||||
(hpgs_ostream_close_func_t) mem_close,
|
|
||||||
(hpgs_ostream_iserror_func_t) mem_iserror,
|
|
||||||
(hpgs_ostream_getbuf_func_t) mem_getbuf,
|
|
||||||
(hpgs_ostream_tell_func_t) mem_tell,
|
|
||||||
(hpgs_ostream_seek_func_t) mem_seek
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Returns a new \c hpgs_ostream created on the heap,
|
|
||||||
which operates on a malloced chunk of memory with
|
|
||||||
the preallocated given size.
|
|
||||||
|
|
||||||
The memory buffer is realloced when the data grows over the
|
|
||||||
given preallocated size.
|
|
||||||
|
|
||||||
Returns a null pointer, when the system is out of memory.
|
|
||||||
*/
|
|
||||||
hpgs_ostream *hpgs_new_mem_ostream (size_t data_reserve)
|
|
||||||
{
|
|
||||||
hpgs_mem_ostream_stream *stream;
|
|
||||||
hpgs_ostream *ret = (hpgs_ostream *)malloc(sizeof(hpgs_ostream));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stream =
|
|
||||||
(hpgs_mem_ostream_stream *)malloc(sizeof(hpgs_mem_ostream_stream));
|
|
||||||
|
|
||||||
if (!stream)
|
|
||||||
{
|
|
||||||
free (ret);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->data = (unsigned char *)malloc(data_reserve);
|
|
||||||
stream->pptr = stream->data;
|
|
||||||
stream->eptr = stream->data ? stream->data+data_reserve : 0;
|
|
||||||
stream->errflg = stream->data ? 0 : 1;
|
|
||||||
|
|
||||||
ret->stream = stream;
|
|
||||||
ret->vtable = &mem_vtable;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_copy_streams (hpgs_ostream *out, hpgs_istream *in)
|
|
||||||
{
|
|
||||||
unsigned char buf[16384];
|
|
||||||
size_t sz;
|
|
||||||
|
|
||||||
while ((sz = hpgs_istream_read(buf,1,sizeof(buf),in)) > 0)
|
|
||||||
if (hpgs_ostream_write(buf,1,sz,out) == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_istream_iserror(in);
|
|
||||||
}
|
|
||||||
@@ -1,716 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspaint.c 375 2007-01-24 16:22:49Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the public API for the pixel painter. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgspaint.h>
|
|
||||||
#include<math.h>
|
|
||||||
#include<assert.h>
|
|
||||||
#include<string.h>
|
|
||||||
#if defined ( __MINGW32__ ) || defined ( _MSC_VER )
|
|
||||||
#include <malloc.h>
|
|
||||||
#else
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#define HPGS_PAINT_DEBUG_ROP3
|
|
||||||
|
|
||||||
/*! \defgroup paint_device Paint device.
|
|
||||||
|
|
||||||
This module contains the workhorse for rendering a scenery to pixel
|
|
||||||
graphics, \c hpgs_paint_device.
|
|
||||||
|
|
||||||
Most notably, you can call \c hpgs_new_paint_device in order to
|
|
||||||
create a new paint device and perform the usual operations
|
|
||||||
\c hpgs_moveto, \c hpgs_lineto, ... on it.
|
|
||||||
|
|
||||||
Details about the implementation are explained in the documentation
|
|
||||||
of \c hpgs_paint_device_st and \c hpgs_paint_clipper_st and the
|
|
||||||
hpyerlinks therein.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* static paint device methods for the hpgs_device vtable. */
|
|
||||||
static int pdv_moveto (hpgs_device *_this, const hpgs_point *p)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (hpgs_paint_path_moveto(pdv->path,p))
|
|
||||||
return hpgs_set_error(hpgs_i18n("moveto error."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_lineto (hpgs_device *_this, const hpgs_point *p)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (hpgs_paint_path_lineto(pdv->path,p))
|
|
||||||
return hpgs_set_error(hpgs_i18n("lineto error."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_curveto (hpgs_device *_this, const hpgs_point *p1,
|
|
||||||
const hpgs_point *p2, const hpgs_point *p3 )
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (hpgs_paint_path_curveto(pdv->path,p1,p2,p3))
|
|
||||||
return hpgs_set_error(hpgs_i18n("curveto error."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_newpath (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
hpgs_paint_path_truncate(pdv->path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_closepath (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (hpgs_paint_path_closepath(pdv->path))
|
|
||||||
return hpgs_set_error(hpgs_i18n("closepath error."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_stroke (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (pdv->path->n_points > 1 ||
|
|
||||||
(pdv->path->n_points == 1 && (pdv->path->points[0].flags&HPGS_POINT_DOT))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!pdv->overscan &&
|
|
||||||
pdv->gstate->linewidth < 1.5 * pdv->path_clipper->yfac)
|
|
||||||
{
|
|
||||||
const hpgs_paint_clipper *clip = pdv->clippers[pdv->current_clipper];
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_thin_cut(pdv->path_clipper,
|
|
||||||
pdv->path,pdv->gstate))
|
|
||||||
return hpgs_set_error(hpgs_i18n("Out of memory cutting thin line."));
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_emit(pdv->image,
|
|
||||||
pdv->path_clipper,clip,
|
|
||||||
&pdv->color,1,1))
|
|
||||||
{
|
|
||||||
if (hpgs_have_error())
|
|
||||||
return hpgs_error_ctxt(hpgs_i18n("stroke: Image error"));
|
|
||||||
|
|
||||||
return hpgs_set_error(hpgs_i18n("stroke: Error emitting scanlines."));
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_paint_clipper_clear(pdv->path_clipper);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hpgs_paint_path *p = hpgs_paint_path_stroke_path(pdv->path,
|
|
||||||
pdv->gstate);
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Out of memory creating stroke path."));
|
|
||||||
|
|
||||||
ret = hpgs_paint_device_fill(pdv,p,HPGS_TRUE,HPGS_TRUE);
|
|
||||||
|
|
||||||
hpgs_paint_path_destroy(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_paint_path_truncate(pdv->path);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Error filling stroke path."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_fill (hpgs_device *_this, hpgs_bool winding)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
int ret = hpgs_paint_device_fill(pdv,pdv->path,winding,HPGS_FALSE);
|
|
||||||
|
|
||||||
hpgs_paint_path_truncate(pdv->path);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_clip (hpgs_device *_this, hpgs_bool winding)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
int ret = hpgs_paint_device_clip(pdv,pdv->path,winding);
|
|
||||||
|
|
||||||
hpgs_paint_path_truncate(pdv->path);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_clipsave (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (pdv->clip_depth >= HPGS_PAINT_MAX_CLIP_DEPTH)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Maximum clip depth of %d exceeded."),
|
|
||||||
HPGS_PAINT_MAX_CLIP_DEPTH);
|
|
||||||
|
|
||||||
pdv->clippers[pdv->clip_depth] = 0;
|
|
||||||
|
|
||||||
++pdv->clip_depth;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_cliprestore (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
--pdv->clip_depth;
|
|
||||||
|
|
||||||
if (pdv->clippers[pdv->clip_depth])
|
|
||||||
{
|
|
||||||
hpgs_paint_clipper_destroy(pdv->clippers[pdv->clip_depth]);
|
|
||||||
pdv->clippers[pdv->clip_depth] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdv->current_clipper < pdv->clip_depth)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (pdv->current_clipper > 0)
|
|
||||||
{
|
|
||||||
--pdv->current_clipper;
|
|
||||||
if (pdv->clippers[pdv->current_clipper])
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hpgs_set_error(hpgs_i18n("cliprestore: No valid clipper found."));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setrgbcolor (hpgs_device *_this, const hpgs_color *rgb)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
pdv->gstate->color = *rgb;
|
|
||||||
|
|
||||||
pdv->color.r = (unsigned char)(rgb->r*255.0);
|
|
||||||
pdv->color.g = (unsigned char)(rgb->g*255.0);
|
|
||||||
pdv->color.b = (unsigned char)(rgb->b*255.0);
|
|
||||||
|
|
||||||
if (hpgs_image_define_color(pdv->image,&pdv->color))
|
|
||||||
return hpgs_error_ctxt("setrgbcolor");
|
|
||||||
|
|
||||||
pdv->gstate->pattern_color = *rgb;
|
|
||||||
|
|
||||||
hpgs_palette_color patcol;
|
|
||||||
|
|
||||||
patcol.r = pdv->color.r & (~pdv->patcol.r);
|
|
||||||
patcol.g = pdv->color.g & (~pdv->patcol.g);
|
|
||||||
patcol.b = pdv->color.b & (~pdv->patcol.b);
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_DEBUG_ROP3
|
|
||||||
hpgs_log("setrgbcol: patcol=%d,%d,%d.\n",patcol.r,patcol.g,patcol.b);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return hpgs_image_setpatcol(pdv->image,&patcol);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setdash (hpgs_device *_this, const float *segs,
|
|
||||||
unsigned n, double d)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (hpgs_gstate_setdash(pdv->gstate,segs,n,d))
|
|
||||||
return hpgs_set_error(hpgs_i18n("setdash: Out of memory."));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setlinewidth(hpgs_device *_this, double lw)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (lw < pdv->thin_alpha * pdv->path_clipper->yfac)
|
|
||||||
pdv->gstate->linewidth = pdv->thin_alpha * pdv->path_clipper->yfac;
|
|
||||||
else
|
|
||||||
pdv->gstate->linewidth = lw;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setlinecap (hpgs_device *_this, hpgs_line_cap lc)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
pdv->gstate->line_cap = lc;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setlinejoin (hpgs_device *_this, hpgs_line_join lj)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
pdv->gstate->line_join = lj;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setmiterlimit (hpgs_device *_this, double l)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
pdv->gstate->miterlimit = l;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setrop3 (hpgs_device *_this, int rop,
|
|
||||||
hpgs_bool src_transparency, hpgs_bool pattern_transparency)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
hpgs_rop3_func_t rop3;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_DEBUG_ROP3
|
|
||||||
hpgs_log("setrop3: rop,src_trans,pat_trans=%d,%d,%d.\n",
|
|
||||||
rop,src_transparency,pattern_transparency);
|
|
||||||
#endif
|
|
||||||
pdv->gstate->rop3 = rop;
|
|
||||||
pdv->gstate->src_transparency = src_transparency;
|
|
||||||
pdv->gstate->pattern_transparency = pattern_transparency;
|
|
||||||
|
|
||||||
rop3 = hpgs_rop3_func(rop,src_transparency,pattern_transparency);
|
|
||||||
|
|
||||||
if (!rop3)
|
|
||||||
return hpgs_set_error(hpgs_i18n("setrop3: Invalid ROP3 %d specified"),rop);
|
|
||||||
|
|
||||||
return hpgs_image_setrop3(pdv->image,rop3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setpatcol(hpgs_device *_this, const hpgs_color *rgb)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
pdv->gstate->pattern_color = *rgb;
|
|
||||||
|
|
||||||
pdv->patcol.r = (unsigned char)(rgb->r * 255.0);
|
|
||||||
pdv->patcol.g = (unsigned char)(rgb->g * 255.0);
|
|
||||||
pdv->patcol.b = (unsigned char)(rgb->b * 255.0);
|
|
||||||
|
|
||||||
hpgs_palette_color patcol;
|
|
||||||
|
|
||||||
patcol.r = pdv->color.r & (~pdv->patcol.r);
|
|
||||||
patcol.g = pdv->color.g & (~pdv->patcol.g);
|
|
||||||
patcol.b = pdv->color.b & (~pdv->patcol.b);
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_DEBUG_ROP3
|
|
||||||
hpgs_log("setpatcol: patcol=%d,%d,%d.\n",patcol.r,patcol.g,patcol.b);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return hpgs_image_setpatcol(pdv->image,&patcol);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_drawimage(hpgs_device *_this,
|
|
||||||
const hpgs_image *img,
|
|
||||||
const hpgs_point *ll, const hpgs_point *lr,
|
|
||||||
const hpgs_point *ur)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
if (!img)
|
|
||||||
return hpgs_set_error(hpgs_i18n("drawimage: Null image specified."));
|
|
||||||
|
|
||||||
hpgs_palette_color patcol;
|
|
||||||
patcol.r = 0;
|
|
||||||
patcol.g = 0;
|
|
||||||
patcol.b = 0;
|
|
||||||
|
|
||||||
if (hpgs_image_setpatcol(pdv->image,&patcol))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (hpgs_paint_device_drawimage(pdv,img,ll,lr,ur))
|
|
||||||
{
|
|
||||||
if (hpgs_have_error())
|
|
||||||
return hpgs_error_ctxt(hpgs_i18n("drawimage error"));
|
|
||||||
|
|
||||||
return hpgs_set_error(hpgs_i18n("drawimage error."));
|
|
||||||
}
|
|
||||||
|
|
||||||
patcol.r = pdv->color.r & (~pdv->patcol.r);
|
|
||||||
patcol.g = pdv->color.g & (~pdv->patcol.g);
|
|
||||||
patcol.b = pdv->color.b & (~pdv->patcol.b);
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_DEBUG_ROP3
|
|
||||||
hpgs_log("setpatcol: patcol=%d,%d,%d.\n",patcol.r,patcol.g,patcol.b);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return hpgs_image_setpatcol(pdv->image,&patcol);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_showpage (hpgs_device *_this, int i)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (i>0 && pdv->filename)
|
|
||||||
{
|
|
||||||
int l = strlen(pdv->filename);
|
|
||||||
char *fn = hpgs_alloca(l+20);
|
|
||||||
char * dot = strrchr(pdv->filename,'.');
|
|
||||||
int pos = dot ? dot-pdv->filename : l;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
_snprintf(fn,l+20,"%.*s%4.4d%s",
|
|
||||||
pos,pdv->filename,i,pdv->filename+pos);
|
|
||||||
#else
|
|
||||||
snprintf(fn,l+20,"%.*s%4.4d%s",
|
|
||||||
pos,pdv->filename,i,pdv->filename+pos);
|
|
||||||
#endif
|
|
||||||
ret = hpgs_image_write(pdv->image,fn);
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
ret = hpgs_image_clear(pdv->image);
|
|
||||||
}
|
|
||||||
else if (pdv->filename == 0 || strlen(pdv->filename) > 0)
|
|
||||||
ret = hpgs_image_write(pdv->image,pdv->filename);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_setplotsize (hpgs_device *_this, const hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (hpgs_bbox_isequal(&pdv->page_bb,bb))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int w = (int)ceil((bb->urx-bb->llx)*pdv->xres);
|
|
||||||
int h = (int)ceil((bb->ury-bb->lly)*pdv->yres);
|
|
||||||
|
|
||||||
if (w<2 || h<2)
|
|
||||||
return hpgs_set_error(hpgs_i18n("setplotsize: The given bounding box result in a null image."));
|
|
||||||
|
|
||||||
if (hpgs_image_resize(pdv->image,w,h))
|
|
||||||
return hpgs_error_ctxt(hpgs_i18n("setplotsize: error resizing image"));
|
|
||||||
|
|
||||||
|
|
||||||
if (pdv->path_clipper) hpgs_paint_clipper_destroy(pdv->path_clipper);
|
|
||||||
|
|
||||||
pdv->path_clipper = hpgs_new_paint_clipper(bb,
|
|
||||||
pdv->image->height,
|
|
||||||
16,pdv->overscan);
|
|
||||||
if (!pdv->path_clipper)
|
|
||||||
return hpgs_set_error(hpgs_i18n("setplotsize: Out of memory allocating path clipper."));
|
|
||||||
|
|
||||||
for (i=0;i<pdv->clip_depth;++i)
|
|
||||||
{
|
|
||||||
if (pdv->clippers[i]) hpgs_paint_clipper_destroy(pdv->clippers[i]);
|
|
||||||
pdv->clippers[i]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial dimension of clip segments is 4.
|
|
||||||
pdv->clippers[0] = hpgs_new_paint_clipper(bb,
|
|
||||||
pdv->image->height,4,pdv->overscan);
|
|
||||||
|
|
||||||
if (!pdv->clippers[0])
|
|
||||||
return hpgs_set_error(hpgs_i18n("setplotsize: Out of memory allocating clip clipper."));
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_reset(pdv->clippers[0],bb->llx,bb->urx))
|
|
||||||
return hpgs_set_error(hpgs_i18n("setplotsize: Out of memory initializing clip clipper."));
|
|
||||||
|
|
||||||
pdv->clip_depth = 1;
|
|
||||||
pdv->current_clipper = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pdv_capabilities (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
|
|
||||||
int ret =
|
|
||||||
HPGS_DEVICE_CAP_RASTER |
|
|
||||||
HPGS_DEVICE_CAP_MULTIPAGE |
|
|
||||||
HPGS_DEVICE_CAP_MULTISIZE |
|
|
||||||
HPGS_DEVICE_CAP_DRAWIMAGE;
|
|
||||||
|
|
||||||
if (pdv->overscan)
|
|
||||||
ret |= HPGS_DEVICE_CAP_ANTIALIAS;
|
|
||||||
|
|
||||||
if (pdv->image->vtable->setrop3)
|
|
||||||
ret |= HPGS_DEVICE_CAP_ROP3;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pdv_destroy (hpgs_device *_this)
|
|
||||||
{
|
|
||||||
hpgs_paint_device *pdv = (hpgs_paint_device *)_this;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (pdv->filename) free(pdv->filename);
|
|
||||||
if (pdv->path) hpgs_paint_path_destroy(pdv->path);
|
|
||||||
if (pdv->path_clipper) hpgs_paint_clipper_destroy(pdv->path_clipper);
|
|
||||||
if (pdv->gstate) hpgs_gstate_destroy(pdv->gstate);
|
|
||||||
if (pdv->image) hpgs_image_destroy(pdv->image);
|
|
||||||
|
|
||||||
for (i=0;i<pdv->clip_depth;++i)
|
|
||||||
if (pdv->clippers[i]) hpgs_paint_clipper_destroy(pdv->clippers[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_device_vtable pdv_vtable =
|
|
||||||
{
|
|
||||||
"hpgs_paint_device",
|
|
||||||
pdv_moveto,
|
|
||||||
pdv_lineto,
|
|
||||||
pdv_curveto,
|
|
||||||
pdv_newpath,
|
|
||||||
pdv_closepath,
|
|
||||||
pdv_stroke,
|
|
||||||
pdv_fill,
|
|
||||||
pdv_clip,
|
|
||||||
pdv_clipsave,
|
|
||||||
pdv_cliprestore,
|
|
||||||
pdv_setrgbcolor,
|
|
||||||
pdv_setdash,
|
|
||||||
pdv_setlinewidth,
|
|
||||||
pdv_setlinecap,
|
|
||||||
pdv_setlinejoin,
|
|
||||||
pdv_setmiterlimit,
|
|
||||||
pdv_setrop3,
|
|
||||||
pdv_setpatcol,
|
|
||||||
pdv_drawimage,
|
|
||||||
pdv_setplotsize,
|
|
||||||
0 /* pdv_getplotsize */,
|
|
||||||
pdv_showpage,
|
|
||||||
0 /* pdv_finish */,
|
|
||||||
pdv_capabilities,
|
|
||||||
pdv_destroy
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Creates a new paint device on the heap.
|
|
||||||
Use \c hpgs_destroy in order to destroy the returned
|
|
||||||
device pointer.
|
|
||||||
|
|
||||||
The bounding box, which is mapped onto the given \c image is passed
|
|
||||||
in as well as the \c antialiasing switch.
|
|
||||||
|
|
||||||
A null pointer is returned, if the system is out of memory.
|
|
||||||
*/
|
|
||||||
hpgs_paint_device *hpgs_new_paint_device(hpgs_image *image,
|
|
||||||
const char *filename,
|
|
||||||
const hpgs_bbox *bb,
|
|
||||||
hpgs_bool antialias )
|
|
||||||
{
|
|
||||||
hpgs_paint_device *ret=(hpgs_paint_device *)malloc(sizeof(hpgs_paint_device));
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret->image = image;
|
|
||||||
|
|
||||||
ret->path = 0;
|
|
||||||
ret->gstate = 0;
|
|
||||||
ret->overscan = antialias;
|
|
||||||
ret->thin_alpha = 0.25;
|
|
||||||
|
|
||||||
if (filename)
|
|
||||||
{
|
|
||||||
ret->filename = strdup(filename);
|
|
||||||
|
|
||||||
if (!ret->filename) goto fatal_error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret->filename = 0;
|
|
||||||
|
|
||||||
memset(ret->clippers,
|
|
||||||
0,HPGS_PAINT_MAX_CLIP_DEPTH * sizeof(hpgs_paint_clipper *));
|
|
||||||
|
|
||||||
ret->path = hpgs_new_paint_path();
|
|
||||||
if (!ret->path) goto fatal_error;
|
|
||||||
|
|
||||||
ret->path_clipper = hpgs_new_paint_clipper(bb,
|
|
||||||
image->height,
|
|
||||||
16,ret->overscan);
|
|
||||||
if (!ret->path_clipper) goto fatal_error;
|
|
||||||
|
|
||||||
ret->gstate = hpgs_new_gstate();
|
|
||||||
if (!ret->gstate) goto fatal_error;
|
|
||||||
|
|
||||||
// Initial dimesion of clip segments is 4.
|
|
||||||
ret->clippers[0] = hpgs_new_paint_clipper(bb,
|
|
||||||
image->height,4,ret->overscan);
|
|
||||||
if (!ret->clippers[0]) goto fatal_error;
|
|
||||||
if (hpgs_paint_clipper_reset(ret->clippers[0],bb->llx,bb->urx))
|
|
||||||
goto fatal_error;
|
|
||||||
|
|
||||||
ret->clip_depth = 1;
|
|
||||||
ret->current_clipper = 0;
|
|
||||||
|
|
||||||
ret->page_bb = *bb;
|
|
||||||
ret->xres = image->width/(bb->urx-bb->llx);
|
|
||||||
ret->yres = image->height/(bb->ury-bb->lly);
|
|
||||||
|
|
||||||
if (hpgs_image_set_resolution(image,72.0*ret->xres,72.0*ret->yres))
|
|
||||||
goto fatal_error;
|
|
||||||
|
|
||||||
ret->image_interpolation = 0;
|
|
||||||
|
|
||||||
ret->color.r = 0;
|
|
||||||
ret->color.g = 0;
|
|
||||||
ret->color.b = 0;
|
|
||||||
ret->color.index = 0;
|
|
||||||
|
|
||||||
ret->patcol.r = 0;
|
|
||||||
ret->patcol.g = 0;
|
|
||||||
ret->patcol.b = 0;
|
|
||||||
|
|
||||||
ret->inherited.vtable = &pdv_vtable;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
fatal_error:
|
|
||||||
if (ret->filename) free(ret->filename);
|
|
||||||
if (ret->path) hpgs_paint_path_destroy(ret->path);
|
|
||||||
if (ret->clippers[0]) hpgs_paint_clipper_destroy(ret->clippers[0]);
|
|
||||||
if (ret->gstate) hpgs_gstate_destroy(ret->gstate);
|
|
||||||
if (ret->image) hpgs_image_destroy(ret->image);
|
|
||||||
free(ret);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Sets the image interpolation value of the given paint device.
|
|
||||||
Currently, the following values are supported:
|
|
||||||
|
|
||||||
\li 0 no image iterpolation
|
|
||||||
\li 1 linear image interpolation.
|
|
||||||
|
|
||||||
Other values specifiying square or cubic interpolation may be
|
|
||||||
supported in the future. The default value is 0.
|
|
||||||
*/
|
|
||||||
void hpgs_paint_device_set_image_interpolation (hpgs_paint_device *pdv, int i)
|
|
||||||
{
|
|
||||||
pdv->image_interpolation = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Sets the minimal alpha value for thin lines, when antialiasing is
|
|
||||||
in effect. The supplied value must be grater than or equal to 0.01 and
|
|
||||||
lesser than or equal to 10.0. Other values are ignored.
|
|
||||||
*/
|
|
||||||
void hpgs_paint_device_set_thin_alpha (hpgs_paint_device *pdv, double a)
|
|
||||||
{
|
|
||||||
if (a > 0.01 && a <= 10.0)
|
|
||||||
pdv->thin_alpha = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Fills the intersection of the given path with the current clip
|
|
||||||
path of the paint device \c pdv using the current graphics state of \c pdv.
|
|
||||||
|
|
||||||
if \c winding is \c HPGS_TRUE, the non-zero winding rule is used for filling,
|
|
||||||
otherwise the exclusive-or rule applies.
|
|
||||||
|
|
||||||
Return values:
|
|
||||||
|
|
||||||
\li 0 Sucess.
|
|
||||||
\li -1 An error ocurred.
|
|
||||||
Call \c hpgs_device_get_error in order to retrieve the error message.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int hpgs_paint_device_fill(hpgs_paint_device *pdv,
|
|
||||||
hpgs_paint_path *path,
|
|
||||||
hpgs_bool winding,
|
|
||||||
hpgs_bool stroke )
|
|
||||||
{
|
|
||||||
const hpgs_paint_clipper *clip = pdv->clippers[pdv->current_clipper];
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_cut(pdv->path_clipper,path))
|
|
||||||
return hpgs_set_error(hpgs_i18n("fill: Error cutting current path."));
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_emit(pdv->image,
|
|
||||||
pdv->path_clipper,clip,
|
|
||||||
&pdv->color,winding,stroke))
|
|
||||||
{
|
|
||||||
if (hpgs_have_error())
|
|
||||||
return hpgs_error_ctxt(hpgs_i18n("fill: Image error"));
|
|
||||||
|
|
||||||
return hpgs_set_error(hpgs_i18n("fill: Error emitting scanlines."));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hpgs_paint_clipper_clear(pdv->path_clipper);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Sets the intersection of the given path with the current clip
|
|
||||||
path of the paint device \c pdv as the current clip path of \c pdv.
|
|
||||||
|
|
||||||
if \c winding is \c HPGS_TRUE, the non-zero winding rule is used for the
|
|
||||||
path intersection, otherwise the exclusive-or rule applies.
|
|
||||||
|
|
||||||
Return values:
|
|
||||||
|
|
||||||
\li 0 Sucess.
|
|
||||||
\li -1 An error ocurred.
|
|
||||||
Call \c hpgs_device_get_error in order to retrieve the error message.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int hpgs_paint_device_clip(hpgs_paint_device *pdv,
|
|
||||||
hpgs_paint_path *path,
|
|
||||||
hpgs_bool winding)
|
|
||||||
{
|
|
||||||
const hpgs_paint_clipper *clip = pdv->clippers[pdv->current_clipper];
|
|
||||||
|
|
||||||
if (hpgs_paint_clipper_cut(pdv->path_clipper,path))
|
|
||||||
return hpgs_set_error(hpgs_i18n("clip: Error cutting current path."));
|
|
||||||
|
|
||||||
hpgs_paint_clipper *nclip =
|
|
||||||
hpgs_paint_clipper_clip(pdv->path_clipper,clip,winding);
|
|
||||||
|
|
||||||
if (!nclip)
|
|
||||||
return hpgs_set_error(hpgs_i18n("clip: Out of memory creating new clipper."));
|
|
||||||
|
|
||||||
// push the new clipper onto the stack of clippers.
|
|
||||||
pdv->current_clipper = pdv->clip_depth-1;
|
|
||||||
|
|
||||||
if (pdv->clippers[pdv->current_clipper])
|
|
||||||
hpgs_paint_clipper_destroy(pdv->clippers[pdv->current_clipper]);
|
|
||||||
|
|
||||||
pdv->clippers[pdv->current_clipper] = nclip;
|
|
||||||
|
|
||||||
hpgs_paint_clipper_clear(pdv->path_clipper);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspaint.h 270 2006-01-29 21:12:23Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The declarations for the pixel painter. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_PAINT_H
|
|
||||||
#define __HPGS_PAINT_H
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \file hpgspaint.h
|
|
||||||
|
|
||||||
\brief Internals of the pixel renderer.
|
|
||||||
|
|
||||||
A header file, which declares the structures and functions internally
|
|
||||||
used by \c hpgs_paint_device.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct hpgs_scanline_point_st hpgs_scanline_point;
|
|
||||||
typedef struct hpgs_paint_scanline_st hpgs_paint_scanline;
|
|
||||||
typedef struct hpgs_paint_clipper_st hpgs_paint_clipper;
|
|
||||||
|
|
||||||
/*! @addtogroup paint_device
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HPGS_PAINT_MAX_CLIP_DEPTH 16
|
|
||||||
|
|
||||||
/*! \brief The pixel rendering vector graphics device.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_paint_device and
|
|
||||||
represents a \c hpgs_device which draws to a given \c hpgs_image.
|
|
||||||
It is capable of drawing polgonal data with optional antialiasing.
|
|
||||||
Image may be drawn using a linear interpolation of the pixel values
|
|
||||||
or uninterpolated.
|
|
||||||
|
|
||||||
The following figure outlines the coordinate setup of a paint device.
|
|
||||||
|
|
||||||
\image html clipper.png
|
|
||||||
\image latex clipper.eps "Coordinate setup of hpgs_paint_device"
|
|
||||||
|
|
||||||
Further details on antialiasing and scanline setup are described in the
|
|
||||||
documentation of \c hpgs_paint_clipper_st.
|
|
||||||
*/
|
|
||||||
struct hpgs_paint_device_st
|
|
||||||
{
|
|
||||||
hpgs_device inherited; /*!< The base device structure. */
|
|
||||||
|
|
||||||
hpgs_image *image; /*!< The image to which we draw. */
|
|
||||||
|
|
||||||
char *filename; /*!< The image filename without an eventual extension. */
|
|
||||||
|
|
||||||
hpgs_bbox page_bb;/*! The bounding box in world coordinates, which is mapped onto
|
|
||||||
the image. */
|
|
||||||
|
|
||||||
double xres; /*!< The resolution of the image in x direction. */
|
|
||||||
double yres; /*!< The resolution of the image in y direction. */
|
|
||||||
|
|
||||||
hpgs_bool overscan;
|
|
||||||
/*!< Specifies, whether we use antialiasing for rendering the image. */
|
|
||||||
double thin_alpha; /*!< The minimal alpha value for antialiased thin lines. */
|
|
||||||
|
|
||||||
hpgs_paint_path *path; /*!< The current path, which is under contruction. */
|
|
||||||
|
|
||||||
hpgs_paint_clipper *path_clipper; /*!< The mapping of the current path onto the defined scanlines. */
|
|
||||||
|
|
||||||
|
|
||||||
hpgs_paint_clipper *clippers[HPGS_PAINT_MAX_CLIP_DEPTH];
|
|
||||||
/*!< A stack of mappings of the clip path' of onto the defined scanlines. */
|
|
||||||
|
|
||||||
|
|
||||||
int current_clipper; /*!< The position of the current clip path in \c clippers. */
|
|
||||||
int clip_depth;
|
|
||||||
/*!< The current depth of the clip stack, i.e. the number of time
|
|
||||||
\c hpgs_clip or \c hpgs_eoclip has been called. */
|
|
||||||
|
|
||||||
hpgs_gstate *gstate; /*!< The graphics state. */
|
|
||||||
|
|
||||||
hpgs_paint_color color; /*!< The current color transformed to a device color. */
|
|
||||||
hpgs_palette_color patcol; /*!< The current pattern color transformed to a device color. */
|
|
||||||
|
|
||||||
int image_interpolation; /*!< A flag holding whether we do image interpolation. */
|
|
||||||
};
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_device_fill(hpgs_paint_device *pdv,
|
|
||||||
hpgs_paint_path *path,
|
|
||||||
hpgs_bool winding,
|
|
||||||
hpgs_bool stroke);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_device_clip(hpgs_paint_device *pdv,
|
|
||||||
hpgs_paint_path *path,
|
|
||||||
hpgs_bool winding);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_device_drawimage(hpgs_paint_device *pdv,
|
|
||||||
const hpgs_image *img,
|
|
||||||
const hpgs_point *ll, const hpgs_point *lr,
|
|
||||||
const hpgs_point *ur);
|
|
||||||
|
|
||||||
/*! @} */ /* end of group paint_device */
|
|
||||||
|
|
||||||
/*! @addtogroup path
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HPGS_BEZIER_NSEGS 16
|
|
||||||
|
|
||||||
typedef struct hpgs_bezier_length_st hpgs_bezier_length;
|
|
||||||
|
|
||||||
/*! \brief A structure for holding intermediate values for length
|
|
||||||
calculations of a bezier spline.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_bezier_length and holds
|
|
||||||
internals of a bezier spline used during length calculations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct hpgs_bezier_length_st
|
|
||||||
{
|
|
||||||
double l[HPGS_BEZIER_NSEGS+1]; /*!< The length of the spline from the beginning to the parameter -0.5+i/HPGS_BEZIER_NSEGS. */
|
|
||||||
double dl[HPGS_BEZIER_NSEGS+1]; /*!< The derivative of the length of the spline at the parameter -0.5+i/HPGS_BEZIER_NSEGS. */
|
|
||||||
};
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_bezier_length_init(hpgs_bezier_length *b,
|
|
||||||
const hpgs_paint_path *path, int i);
|
|
||||||
HPGS_INTERNAL_API double hpgs_bezier_length_param(const hpgs_bezier_length *b, double l);
|
|
||||||
|
|
||||||
/*! @} */ /* end of group path */
|
|
||||||
|
|
||||||
/*! @addtogroup scanline
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \brief An intersection point of a path with a scanline.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_scanline_point and holds
|
|
||||||
the information of an intersection point of a path with a scanline.
|
|
||||||
*/
|
|
||||||
struct hpgs_scanline_point_st
|
|
||||||
{
|
|
||||||
double x;
|
|
||||||
/*!< The x coordinate of the intersection point of the path with the scanline. */
|
|
||||||
|
|
||||||
int order;
|
|
||||||
/*!< The order of the intersection.
|
|
||||||
An \c order of 1 means an upward intersection, -1 means a downward intersection.
|
|
||||||
Horizontal intersection are stored as two distinct intersection points with the same
|
|
||||||
x coordinate. If antialiasing is used, the order represents a delta of a broken down
|
|
||||||
winding value. A order of 256 means that the scanline is intersected from the bottom
|
|
||||||
to the top of a physical image row between the previous and the actual intersection
|
|
||||||
point. if The order is smaller than 256, the physical row is not touched in its whole
|
|
||||||
extend an a corresponding alpha value less than 1 is generated. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A scanline of the pixel renderer.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_paint_scanline and holds
|
|
||||||
the intersections points of a path with a scanline.
|
|
||||||
*/
|
|
||||||
struct hpgs_paint_scanline_st
|
|
||||||
{
|
|
||||||
/*@{*/
|
|
||||||
/*! A vector of intersection points.
|
|
||||||
*/
|
|
||||||
hpgs_scanline_point *points;
|
|
||||||
int points_malloc_size;
|
|
||||||
int n_points;
|
|
||||||
/*@}*/
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A collection of scanlines for mapping paths onto images.
|
|
||||||
|
|
||||||
This structure has a public alias \c hpgs_paint_clipper and holds
|
|
||||||
intersection points of a path with a rectangular region represented
|
|
||||||
by a series of equidistantly distributed scanlines.
|
|
||||||
|
|
||||||
The \c overscan member determines, whether we use antialiasing for
|
|
||||||
mappinng the path. The name of this structure member is historical,
|
|
||||||
because up to \c hpgs-0.8.x the antialiasing renderer effectively used
|
|
||||||
more than one scanline per physical image row in order to caclulate
|
|
||||||
alpha values.
|
|
||||||
|
|
||||||
Nowadays a scanline always represents the middle of the
|
|
||||||
corresponding physical row of the image as sketch in the folowing figure,
|
|
||||||
which show the generated segment for non-antialiased rendering.
|
|
||||||
|
|
||||||
\image html scanline_0.png
|
|
||||||
\image latex scanline_0.eps "scanline setup and pixel filling without antialiasing."
|
|
||||||
|
|
||||||
If \c overscan is non-zero, the segment generator caclulates slopes of the
|
|
||||||
trapezoids, which are generated by the path segments cutting the boundaries
|
|
||||||
between two physical grid lines as sketched in the following figure.
|
|
||||||
|
|
||||||
\image html scanline_n.png
|
|
||||||
\image latex scanline_n.eps "scanline setup and alpha generation with antialiasing."
|
|
||||||
|
|
||||||
*/
|
|
||||||
struct hpgs_paint_clipper_st
|
|
||||||
{
|
|
||||||
/*@{ */
|
|
||||||
/*! The vector of scanlines in this clipper.
|
|
||||||
*/
|
|
||||||
hpgs_paint_scanline *scanlines;
|
|
||||||
int n_scanlines;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
hpgs_bbox bb; /*! The bounding box of this clipper in world coordinates. */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! The mapping of scanline numbers to world coordinates.
|
|
||||||
\c iscan=(y0-y)/yfac and \c y=y0-iscan*yfac.
|
|
||||||
*/
|
|
||||||
double yfac; // height of a single scanline.
|
|
||||||
double y0; // y for scanline 0
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
hpgs_bool overscan; /*!< Do we use antialiasing ?. */
|
|
||||||
int height; /*!< Number of physical pixels of the underlying image. */
|
|
||||||
|
|
||||||
int iscan0; /*!< The first scanline with non-zero intersections. */
|
|
||||||
int iscan1; /*!< The last scanline with non-zero intersections. */
|
|
||||||
};
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API hpgs_paint_clipper *hpgs_new_paint_clipper(const hpgs_bbox *bb,
|
|
||||||
int height,
|
|
||||||
int scanline_msize,
|
|
||||||
int overscan);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API hpgs_paint_clipper *hpgs_paint_clipper_clip(const hpgs_paint_clipper *orig,
|
|
||||||
const hpgs_paint_clipper *clip,
|
|
||||||
hpgs_bool winding);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_clipper_cut(hpgs_paint_clipper *c,
|
|
||||||
hpgs_paint_path *path);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_clipper_thin_cut(hpgs_paint_clipper *c,
|
|
||||||
hpgs_paint_path *path,
|
|
||||||
const hpgs_gstate *gstate);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_clipper_emit (hpgs_image *image,
|
|
||||||
const hpgs_paint_clipper *img,
|
|
||||||
const hpgs_paint_clipper *clip,
|
|
||||||
const hpgs_paint_color *c,
|
|
||||||
hpgs_bool winding,
|
|
||||||
hpgs_bool stroke);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_paint_clipper_reset(hpgs_paint_clipper *c, double llx, double urx);
|
|
||||||
HPGS_INTERNAL_API void hpgs_paint_clipper_clear(hpgs_paint_clipper *c);
|
|
||||||
HPGS_INTERNAL_API void hpgs_paint_clipper_destroy(hpgs_paint_clipper *c);
|
|
||||||
|
|
||||||
/*! @} */ /* end of group scanline */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // end of extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! __HPGS_PAINT_H */
|
|
||||||
@@ -1,469 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspaintimage.c 281 2006-02-25 19:40:31Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the public API for the pixel painter. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgspaint.h>
|
|
||||||
#include<math.h>
|
|
||||||
#include<assert.h>
|
|
||||||
#include<string.h>
|
|
||||||
|
|
||||||
//#define HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
static void log_mat_6(const char *lead, const double *mat)
|
|
||||||
{
|
|
||||||
hpgs_log("%s%10lg,%10lg,%10lg\n%*s%10lg,%10lg,%10lg.\n",
|
|
||||||
lead,mat->dx,mat->mxx,mat->mxy,
|
|
||||||
strlen(lead)," ",mat->dy,mat->myx,mat->myy);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// multiplicates the given vector with the specified matrix.
|
|
||||||
// This is here in order to allow efficient inlining of the code.
|
|
||||||
//
|
|
||||||
static void mat_6_mul(hpgs_point *pout, const hpgs_matrix *mat, double xin, double yin)
|
|
||||||
{
|
|
||||||
pout->x = mat->dx + mat->mxx * xin + mat->mxy * yin;
|
|
||||||
pout->y = mat->dy + mat->myx * xin + mat->myy * yin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// build matrix from destination to source pixel coordinates.
|
|
||||||
static void build_inv_matrix(hpgs_matrix *m,
|
|
||||||
const hpgs_paint_clipper *c,
|
|
||||||
const hpgs_image *dest,
|
|
||||||
const hpgs_image *src,
|
|
||||||
const hpgs_point *ll,
|
|
||||||
const hpgs_point *ul,
|
|
||||||
const hpgs_point *lr,
|
|
||||||
const hpgs_point *ur)
|
|
||||||
{
|
|
||||||
// image to device coordinates.
|
|
||||||
hpgs_matrix a = { ul->x, ul->y,
|
|
||||||
(lr->x-ll->x)/src->width, (lr->x-ur->x)/src->height,
|
|
||||||
(lr->y-ll->y)/src->width, (lr->y-ur->y)/src->height };
|
|
||||||
|
|
||||||
// device to target raster coordinates.
|
|
||||||
hpgs_matrix b = {-0.5-c->bb.llx*dest->width/(c->bb.urx-c->bb.llx), c->y0/c->yfac,
|
|
||||||
dest->width/(c->bb.urx-c->bb.llx), 0.0,
|
|
||||||
0.0, -1.0/c->yfac };
|
|
||||||
|
|
||||||
hpgs_matrix tmp;
|
|
||||||
|
|
||||||
// take half a pixel into account.
|
|
||||||
a.dx += 0.5 * (a.mxx + a.mxy);
|
|
||||||
a.dy += 0.5 * (a.myx + a.myy);
|
|
||||||
|
|
||||||
hpgs_matrix_concat(&tmp,&b,&a);
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
log_mat_6("a = ",a);
|
|
||||||
log_mat_6("b = ",b);
|
|
||||||
log_mat_6("b*a = ",tmp);
|
|
||||||
#endif
|
|
||||||
hpgs_matrix_invert(m,&tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef int (*put_point_func_t)(hpgs_image *, const hpgs_image *,
|
|
||||||
int, int, const hpgs_point *, double);
|
|
||||||
|
|
||||||
static int put_point_0(hpgs_image *dest, const hpgs_image *src,
|
|
||||||
int dest_i, int dest_j, const hpgs_point *src_point,
|
|
||||||
double alpha)
|
|
||||||
{
|
|
||||||
hpgs_paint_color col;
|
|
||||||
|
|
||||||
double a;
|
|
||||||
|
|
||||||
int src_i = (int)rint(src_point->x);
|
|
||||||
int src_j = (int)rint(src_point->y);
|
|
||||||
|
|
||||||
if (src_i < 0 || src_i >= src->width) return 0;
|
|
||||||
if (src_j < 0 || src_j >= src->height) return 0;
|
|
||||||
|
|
||||||
hpgs_image_get_pixel(src,src_i,src_j,&col,&a);
|
|
||||||
|
|
||||||
if (hpgs_image_define_color (dest,&col))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_image_rop3_pixel(dest,dest_i,dest_j,&col,
|
|
||||||
alpha*a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int put_point_1(hpgs_image *dest, const hpgs_image *src,
|
|
||||||
int dest_i, int dest_j, const hpgs_point *src_point,
|
|
||||||
double alpha)
|
|
||||||
{
|
|
||||||
hpgs_paint_color col;
|
|
||||||
|
|
||||||
double aa,a=0.0;
|
|
||||||
double r=0.0,g=0.0,b=0.0;
|
|
||||||
|
|
||||||
double w;
|
|
||||||
double sw = 0.0;
|
|
||||||
|
|
||||||
int src_i = (int)ceil(src_point->x);
|
|
||||||
int src_j = (int)ceil(src_point->y);
|
|
||||||
|
|
||||||
double wx = ceil(src_point->x) - src_point->x;
|
|
||||||
double wy = ceil(src_point->y) - src_point->y;
|
|
||||||
|
|
||||||
if (src_i < 0 || src_i > src->width) return 0;
|
|
||||||
if (src_j < 0 || src_j > src->height) return 0;
|
|
||||||
|
|
||||||
if (src_i > 0)
|
|
||||||
{
|
|
||||||
if (src_j > 0)
|
|
||||||
{
|
|
||||||
hpgs_image_get_pixel(src,src_i-1,src_j-1,&col,&aa);
|
|
||||||
w = wx+wy;
|
|
||||||
r+=w*col.r;
|
|
||||||
g+=w*col.g;
|
|
||||||
b+=w*col.b;
|
|
||||||
a += w*aa;
|
|
||||||
sw += w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_j < src->height)
|
|
||||||
{
|
|
||||||
hpgs_image_get_pixel(src,src_i-1,src_j,&col,&aa);
|
|
||||||
w = 1.0-wy+wx;
|
|
||||||
r+=w*col.r;
|
|
||||||
g+=w*col.g;
|
|
||||||
b+=w*col.b;
|
|
||||||
a += w*aa;
|
|
||||||
sw += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_i < src->width)
|
|
||||||
{
|
|
||||||
if (src_j > 0)
|
|
||||||
{
|
|
||||||
hpgs_image_get_pixel(src,src_i,src_j-1,&col,&aa);
|
|
||||||
w = 1.0-wx+wy;
|
|
||||||
r+=w*col.r;
|
|
||||||
g+=w*col.g;
|
|
||||||
b+=w*col.b;
|
|
||||||
a += w*aa;
|
|
||||||
sw += w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_j < src->height)
|
|
||||||
{
|
|
||||||
hpgs_image_get_pixel(src,src_i,src_j,&col,&aa);
|
|
||||||
w=2.0-wx-wy;
|
|
||||||
r+=w*col.r;
|
|
||||||
g+=w*col.g;
|
|
||||||
b+=w*col.b;
|
|
||||||
a += w*aa;
|
|
||||||
sw += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sw) return 0;
|
|
||||||
|
|
||||||
col.r = r / sw;
|
|
||||||
col.g = g / sw;
|
|
||||||
col.b = b / sw;
|
|
||||||
|
|
||||||
if (hpgs_image_define_color (dest,&col))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_image_rop3_pixel(dest,dest_i,dest_j,&col,
|
|
||||||
0.25*alpha*a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
|
|
||||||
Draws the intersection of the given image with the current clip
|
|
||||||
path of the paint device \c pdv to the destination image of \c pdv.
|
|
||||||
|
|
||||||
The arguments \c ll, \c lr and \c ur are the
|
|
||||||
lower left, lower right and upper right corner of the drawn image
|
|
||||||
in world coordinates.
|
|
||||||
|
|
||||||
Return values:
|
|
||||||
|
|
||||||
\li 0 Sucess.
|
|
||||||
\li -1 An error ocurred.
|
|
||||||
Call \c hpgs_device_get_error in order to retrieve the error message.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int hpgs_paint_device_drawimage(hpgs_paint_device *pdv,
|
|
||||||
const hpgs_image *img,
|
|
||||||
const hpgs_point *ll, const hpgs_point *lr,
|
|
||||||
const hpgs_point *ur)
|
|
||||||
{
|
|
||||||
const hpgs_paint_clipper *c = pdv->clippers[pdv->current_clipper];
|
|
||||||
put_point_func_t put_point_func = put_point_0;
|
|
||||||
hpgs_point ul;
|
|
||||||
double ll_i,lr_i,ur_i,ul_i;
|
|
||||||
int iscan0;
|
|
||||||
int iscan1;
|
|
||||||
int iscan;
|
|
||||||
hpgs_matrix imat[6];
|
|
||||||
|
|
||||||
if (pdv->image_interpolation)
|
|
||||||
put_point_func = put_point_1;
|
|
||||||
|
|
||||||
ul.x = ll->x + (ur->x - lr->x);
|
|
||||||
ul.y = ll->y + (ur->y - lr->y);
|
|
||||||
|
|
||||||
build_inv_matrix(imat,c,pdv->image,img,ll,&ul,lr,ur);
|
|
||||||
|
|
||||||
ll_i = (c->y0 - ll->y)/c->yfac;
|
|
||||||
lr_i = (c->y0 - lr->y)/c->yfac;
|
|
||||||
ur_i = (c->y0 - ur->y)/c->yfac;
|
|
||||||
ul_i = (c->y0 - ul.y)/c->yfac;
|
|
||||||
|
|
||||||
iscan0 = (int)ceil(ll_i);
|
|
||||||
if (lr_i < iscan0) iscan0 = (int)ceil(lr_i);
|
|
||||||
if (ur_i < iscan0) iscan0 = (int)ceil(ur_i);
|
|
||||||
if (ul_i < iscan0) iscan0 = (int)ceil(ul_i);
|
|
||||||
|
|
||||||
if (iscan0 < c->iscan0) iscan0 = c->iscan0;
|
|
||||||
|
|
||||||
iscan1 = (int)floor(ll_i);
|
|
||||||
if (lr_i > iscan1) iscan1 = (int)floor(lr_i);
|
|
||||||
if (ur_i > iscan1) iscan1 = (int)floor(ur_i);
|
|
||||||
if (ul_i > iscan1) iscan1 = (int)floor(ul_i);
|
|
||||||
|
|
||||||
if (iscan1 > c->iscan1) iscan1 = c->iscan1;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
hpgs_log("ll_i,lr_i,ur_i,ul_i,iscan0,iscan1=%lg,%lg,%lg,%lg,%d,%d.\n",
|
|
||||||
ll_i,lr_i,ur_i,ul_i,iscan0,iscan1);
|
|
||||||
|
|
||||||
print_mat_6(stderr,"imat = ",imat);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (iscan = iscan0; iscan <= iscan1; ++iscan)
|
|
||||||
{
|
|
||||||
double x[2];
|
|
||||||
int ix = 0;
|
|
||||||
int io;
|
|
||||||
const hpgs_paint_scanline *scanline = c->scanlines+iscan;
|
|
||||||
|
|
||||||
if ((iscan > ll_i && iscan < lr_i) ||
|
|
||||||
(iscan < ll_i && iscan > lr_i) )
|
|
||||||
{
|
|
||||||
x[ix] = ((ll_i - iscan)*lr->x + (iscan - lr_i)*ll->x) / (ll_i-lr_i);
|
|
||||||
++ix;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((iscan > lr_i && iscan < ur_i) ||
|
|
||||||
(iscan < lr_i && iscan > ur_i) )
|
|
||||||
{
|
|
||||||
x[ix] = ((lr_i - iscan)*ur->x + (iscan - ur_i)*lr->x) / (lr_i-ur_i);
|
|
||||||
++ix;
|
|
||||||
}
|
|
||||||
if ((iscan > ur_i && iscan < ul_i) ||
|
|
||||||
(iscan < ur_i && iscan > ul_i) )
|
|
||||||
{
|
|
||||||
x[ix] = ((ur_i - iscan)*ul.x + (iscan - ul_i)*ur->x) / (ur_i-ul_i);
|
|
||||||
++ix;
|
|
||||||
}
|
|
||||||
if ((iscan > ul_i && iscan < ll_i) ||
|
|
||||||
(iscan < ul_i && iscan > ll_i) )
|
|
||||||
{
|
|
||||||
x[ix] = ((ul_i - iscan)*ll->x + (iscan - ll_i)*ul.x) / (ul_i-ll_i);
|
|
||||||
++ix;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ix!=2) continue;
|
|
||||||
|
|
||||||
if (x[0] > x[1])
|
|
||||||
{
|
|
||||||
double tmp = x[0];
|
|
||||||
x[0] = x[1];
|
|
||||||
x[1] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdv->overscan)
|
|
||||||
{
|
|
||||||
int out_state = 0;
|
|
||||||
io = 0;
|
|
||||||
|
|
||||||
// go through clip segments antialiased
|
|
||||||
while (io<scanline->n_points)
|
|
||||||
{
|
|
||||||
double xleft,xright,ixleft,ixright;
|
|
||||||
double ileft,iright,ii,alpha_left,alpha_right;
|
|
||||||
hpgs_point src_point;
|
|
||||||
|
|
||||||
xleft= scanline->points[io].x;
|
|
||||||
|
|
||||||
while (io<scanline->n_points && scanline->points[io].x == xleft)
|
|
||||||
{
|
|
||||||
out_state += scanline->points[io].order;
|
|
||||||
++io;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io >= scanline->n_points) break;
|
|
||||||
|
|
||||||
alpha_left = out_state/256.0;
|
|
||||||
|
|
||||||
xright = scanline->points[io].x;
|
|
||||||
alpha_right = (out_state+scanline->points[io].order)/256.0;
|
|
||||||
|
|
||||||
ixright = xright;
|
|
||||||
ixleft = xleft;
|
|
||||||
|
|
||||||
if (ixleft < x[0]) ixleft = x[0];
|
|
||||||
if (ixleft > x[1]) ixleft = x[1];
|
|
||||||
|
|
||||||
if (ixright < x[0]) ixright = x[0];
|
|
||||||
if (ixright > x[1]) ixright = x[1];
|
|
||||||
|
|
||||||
if ((alpha_left == 0.0 && alpha_right == 0.0) ||
|
|
||||||
ixleft >= ixright) continue;
|
|
||||||
|
|
||||||
ixleft = pdv->image->width*(ixleft-c->bb.llx) / (c->bb.urx-c->bb.llx);
|
|
||||||
ixright = pdv->image->width*(ixright-c->bb.llx) / (c->bb.urx-c->bb.llx);
|
|
||||||
|
|
||||||
ileft = ceil(ixleft);
|
|
||||||
iright = floor(ixright);
|
|
||||||
|
|
||||||
// output left corner points with alpha
|
|
||||||
if (ileft >= 1.0)
|
|
||||||
{
|
|
||||||
double alpha = (ileft - ixleft) *
|
|
||||||
(alpha_left*(xright-0.5*(ileft+xleft))+alpha_right*(0.5*(ileft+xleft)-xleft))/(xright-xleft);
|
|
||||||
|
|
||||||
mat_6_mul(&src_point,imat,ileft-1.0,iscan);
|
|
||||||
|
|
||||||
if (put_point_func(pdv->image,img,ileft-1.0,iscan,&src_point,alpha))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
hpgs_log("src: %lg,%lg, dest: %lg,%d.\n",
|
|
||||||
src_point->x,src_point->y,ileft-1.0,iscan);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// output intermediate pixels.
|
|
||||||
for (ii = ileft; ii < iright; ++ii)
|
|
||||||
{
|
|
||||||
double alpha = (alpha_left*(xright-(ii+0.5))+alpha_right*((ii+0.5)-xleft))/(xright-xleft);
|
|
||||||
|
|
||||||
mat_6_mul(&src_point,imat,ii,iscan);
|
|
||||||
if (put_point_func(pdv->image,img,ii,iscan,&src_point,alpha))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// output right corner points with alpha
|
|
||||||
if (iright >= ileft && iright < pdv->image->width)
|
|
||||||
{
|
|
||||||
double alpha = (ixright - iright) *
|
|
||||||
(alpha_left*(xright-0.5*(iright+xright))+alpha_right*(0.5*(iright+xright)-xleft))/(xright-xleft);
|
|
||||||
|
|
||||||
mat_6_mul(&src_point,imat,iright,iscan);
|
|
||||||
|
|
||||||
if (put_point_func(pdv->image,img,iright,iscan,&src_point,alpha))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
hpgs_log("src: %lg,%lg, dest: %lg,%d.\n",
|
|
||||||
src_point->x,src_point->y,iright,iscan);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// go through clip segments - non-antialiased
|
|
||||||
for (io = 0; io+1<scanline->n_points; io+=2)
|
|
||||||
{
|
|
||||||
double xleft= scanline->points[io].x;
|
|
||||||
double xright= scanline->points[io+1].x;
|
|
||||||
double ileft,iright,ii;
|
|
||||||
hpgs_point src_point;
|
|
||||||
|
|
||||||
if (xleft < x[0]) xleft = x[0];
|
|
||||||
if (xleft > x[1]) xleft = x[1];
|
|
||||||
|
|
||||||
if (xright < x[0]) xright = x[0];
|
|
||||||
if (xright > x[1]) xright = x[1];
|
|
||||||
|
|
||||||
if (xleft >= xright) continue;
|
|
||||||
|
|
||||||
xleft = pdv->image->width*(xleft-c->bb.llx) / (c->bb.urx-c->bb.llx);
|
|
||||||
xright = pdv->image->width*(xright-c->bb.llx) / (c->bb.urx-c->bb.llx);
|
|
||||||
|
|
||||||
ileft = ceil(xleft);
|
|
||||||
iright = floor(xright);
|
|
||||||
|
|
||||||
// output left corner points with alpha
|
|
||||||
if (ileft >= 1.0)
|
|
||||||
{
|
|
||||||
double alpha = ileft - xleft;
|
|
||||||
|
|
||||||
mat_6_mul(&src_point,imat,ileft-1.0,iscan);
|
|
||||||
|
|
||||||
if (put_point_func(pdv->image,img,ileft-1.0,iscan,&src_point,alpha))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
hpgs_log("src: %lg,%lg, dest: %lg,%d.\n",
|
|
||||||
src_point->x,src_point->y,ileft-1.0,iscan);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// output intermediate pixels.
|
|
||||||
for (ii = ileft; ii < iright; ++ii)
|
|
||||||
{
|
|
||||||
mat_6_mul(&src_point,imat,ii,iscan);
|
|
||||||
if (put_point_func(pdv->image,img,ii,iscan,&src_point,1.0))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// output right corner points with alpha
|
|
||||||
if (iright >= ileft && iright < pdv->image->width)
|
|
||||||
{
|
|
||||||
double alpha = xright - iright;
|
|
||||||
|
|
||||||
mat_6_mul(&src_point,imat,iright,iscan);
|
|
||||||
|
|
||||||
if (put_point_func(pdv->image,img,iright,iscan,&src_point,alpha))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef HPGS_PAINT_IMAGE_DEBUG
|
|
||||||
hpgs_log("src: %lg,%lg, dest: %lg,%d.\n",
|
|
||||||
src_point->x,src_point->y,iright,iscan);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,290 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspe.c 347 2006-09-21 09:36:01Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
//#define HPGS_DEBUG_PE
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command PE (Polyline Encoded)
|
|
||||||
*/
|
|
||||||
static int base32_decode (hpgs_reader *reader, unsigned *value)
|
|
||||||
{
|
|
||||||
int digit;
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
*value=0;
|
|
||||||
|
|
||||||
while (i<7)
|
|
||||||
{
|
|
||||||
if (reader->last_byte == EOF) return -1;
|
|
||||||
|
|
||||||
reader->last_byte &= 0x7f;
|
|
||||||
|
|
||||||
if (reader->last_byte > 94)
|
|
||||||
digit = reader->last_byte - 95;
|
|
||||||
else
|
|
||||||
digit = reader->last_byte - 63;
|
|
||||||
|
|
||||||
if (digit >= 0 && digit <= 31)
|
|
||||||
{
|
|
||||||
*value |= digit << (5*i);
|
|
||||||
|
|
||||||
if (reader->last_byte > 94) return 0;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// ignore all escape characters, including space.
|
|
||||||
if (reader->last_byte > 32) return -1;
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int base64_decode (hpgs_reader *reader, unsigned *value)
|
|
||||||
{
|
|
||||||
int digit;
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
*value=0;
|
|
||||||
|
|
||||||
while (i<6)
|
|
||||||
{
|
|
||||||
if (reader->last_byte == EOF) return -1;
|
|
||||||
|
|
||||||
if (reader->last_byte > 190)
|
|
||||||
digit = reader->last_byte - 191;
|
|
||||||
else
|
|
||||||
digit = reader->last_byte - 63;
|
|
||||||
|
|
||||||
if (digit >= 0 && digit <= 63)
|
|
||||||
{
|
|
||||||
*value |= digit << (6*i);
|
|
||||||
|
|
||||||
if (reader->last_byte > 190) return 0;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// ignore all escape characters, including space.
|
|
||||||
if (reader->last_byte > 32) return -1;
|
|
||||||
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int int_decode (hpgs_reader *reader, int *value, int b32)
|
|
||||||
{
|
|
||||||
unsigned uval;
|
|
||||||
|
|
||||||
if (b32)
|
|
||||||
{ if (base32_decode(reader,&uval)) return -1; }
|
|
||||||
else
|
|
||||||
{ if (base64_decode(reader,&uval)) return -1; }
|
|
||||||
|
|
||||||
if (uval & 1)
|
|
||||||
*value = - (uval >> 1);
|
|
||||||
else
|
|
||||||
*value = uval >> 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int double_decode (hpgs_reader *reader, double *value,
|
|
||||||
double fract_fac, int b32)
|
|
||||||
{
|
|
||||||
int int_val;
|
|
||||||
|
|
||||||
if (int_decode(reader,&int_val,b32))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
*value = int_val * fract_fac;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int coord_decode (hpgs_reader *reader, hpgs_point *p,
|
|
||||||
double fract_fac, int b32, int rel)
|
|
||||||
{
|
|
||||||
if (double_decode (reader,&p->x,fract_fac,b32)) return -1;
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (double_decode (reader,&p->y,fract_fac,b32)) return -1;
|
|
||||||
|
|
||||||
if (rel)
|
|
||||||
{
|
|
||||||
hpgs_matrix_scale (p,&reader->total_matrix,p);
|
|
||||||
p->x+=reader->current_point.x;
|
|
||||||
p->y+=reader->current_point.y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hpgs_matrix_xform (p,&reader->total_matrix,p);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int hpgs_reader_do_PE(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
hpgs_point p0;
|
|
||||||
hpgs_point p;
|
|
||||||
|
|
||||||
double fract_fac = 1.0;
|
|
||||||
int rel = 1;
|
|
||||||
int b32 = 0;
|
|
||||||
int rect = 0;
|
|
||||||
reader->pen_down = 1;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_PE
|
|
||||||
hpgs_log("PE start ***************\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
|
|
||||||
if (reader->last_byte == EOF || reader->last_byte == ';')
|
|
||||||
{
|
|
||||||
reader->eoc = 1;
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (reader->last_byte & 0x7f)
|
|
||||||
{
|
|
||||||
case '7':
|
|
||||||
b32 = 1;
|
|
||||||
break;
|
|
||||||
case '9':
|
|
||||||
rect = 1;
|
|
||||||
reader->pen_down = 0;
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
{
|
|
||||||
int pen;
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (int_decode(reader,&pen,b32)) return -1;
|
|
||||||
if (hpgs_reader_do_setpen(reader,pen)) return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
{
|
|
||||||
int fract_bits;
|
|
||||||
reader->last_byte = hpgs_getc(reader->in);
|
|
||||||
if (int_decode(reader,&fract_bits,b32)) return -1;
|
|
||||||
|
|
||||||
fract_fac = 1.0;
|
|
||||||
while (--fract_bits >= 0)
|
|
||||||
fract_fac *= 0.5;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
reader->pen_down = 0;
|
|
||||||
rect = 0;
|
|
||||||
break;
|
|
||||||
case '=':
|
|
||||||
rel = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (isspace(reader->last_byte)) break;
|
|
||||||
|
|
||||||
if (coord_decode(reader,&p,fract_fac,b32,rel))
|
|
||||||
{
|
|
||||||
// Well, some HPGL drivers are so broken, that they
|
|
||||||
// can't write decent PE vommands.
|
|
||||||
// So let's hand over control to the recovery code in
|
|
||||||
// hpgs_read().
|
|
||||||
//
|
|
||||||
if (reader->last_byte != EOF)
|
|
||||||
{
|
|
||||||
reader->eoc = 1;
|
|
||||||
reader->bytes_ignored = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_PE
|
|
||||||
hpgs_log("p,down,rect = (%lg,%lg),%d,%d.\n",p.x,p.y,reader->pen_down,rect);
|
|
||||||
#endif
|
|
||||||
switch (rect)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
p0 = p;
|
|
||||||
if (hpgs_reader_moveto(reader,&p0)) return -1;
|
|
||||||
rect = 2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
hpgs_point pp;
|
|
||||||
pp.x=p.x;
|
|
||||||
pp.y=p0.y;
|
|
||||||
if (hpgs_reader_lineto(reader,&pp)) return -1;
|
|
||||||
if (hpgs_reader_lineto(reader,&p))
|
|
||||||
return -1;
|
|
||||||
pp.x=p0.x;
|
|
||||||
pp.y=p.y;
|
|
||||||
if (hpgs_reader_lineto(reader,&pp)) return -1;
|
|
||||||
if (hpgs_reader_lineto(reader,&p0)) return -1;
|
|
||||||
// only do a fill, if we are not in polygon mode.
|
|
||||||
if (!reader->polygon_mode &&
|
|
||||||
hpgs_reader_fill(reader,1)) return -1;
|
|
||||||
}
|
|
||||||
reader->pen_down = 1;
|
|
||||||
rect = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (reader->pen_down)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_lineto(reader,&p)) return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
if (hpgs_reader_moveto(reader,&p)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->pen_down = 1;
|
|
||||||
}
|
|
||||||
rel = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,421 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspen.c 298 2006-03-05 18:18:03Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
Internal
|
|
||||||
*/
|
|
||||||
static int hpgs_reader_set_number_of_pens(hpgs_reader *reader, int npens)
|
|
||||||
{
|
|
||||||
double *pw =(double *)realloc(reader->pen_widths,npens*sizeof(double));
|
|
||||||
|
|
||||||
if (!pw)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Out of memory growing pen width array."));
|
|
||||||
|
|
||||||
reader->pen_widths = pw;
|
|
||||||
|
|
||||||
hpgs_color *pc = (hpgs_color *)realloc(reader->pen_colors,npens*sizeof(hpgs_color));
|
|
||||||
|
|
||||||
if (!pc)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Out of memory growing pen color array."));
|
|
||||||
|
|
||||||
reader->pen_colors = pc;
|
|
||||||
|
|
||||||
for (;reader->npens<npens;++reader->npens)
|
|
||||||
{
|
|
||||||
reader->pen_widths[reader->npens] = 1.0;
|
|
||||||
reader->pen_colors[reader->npens].r = 0.0;
|
|
||||||
reader->pen_colors[reader->npens].g = 0.0;
|
|
||||||
reader->pen_colors[reader->npens].b = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Do the pen select.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_setpen(hpgs_reader *reader, int pen)
|
|
||||||
{
|
|
||||||
double width;
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
if (pen < 0)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Illegal pen numer %d."),pen);
|
|
||||||
|
|
||||||
if (pen >= reader->npens)
|
|
||||||
{
|
|
||||||
if (pen < 256)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_set_number_of_pens(reader,pen+1))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Illegal pen number %d replaced by %d.\n"),
|
|
||||||
pen, pen % reader->npens);
|
|
||||||
pen = pen % reader->npens;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->current_pen = pen;
|
|
||||||
|
|
||||||
width = reader->pen_widths[pen];
|
|
||||||
|
|
||||||
if (reader->pen_width_relative)
|
|
||||||
width *= hypot(reader->P2.x-reader->P1.x,
|
|
||||||
reader->P2.y-reader->P1.y ) * 0.001 * HP_TO_PT;
|
|
||||||
else
|
|
||||||
width *= HP_TO_PT / reader->world_scale;
|
|
||||||
|
|
||||||
width *= reader->page_scale;
|
|
||||||
|
|
||||||
if (hpgs_setlinewidth(reader->device,width*reader->lw_factor))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_setrgbcolor(reader->device,
|
|
||||||
&reader->pen_colors[pen]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command NP (Number of Pens)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_NP (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int npens=8;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&npens)) return -1;
|
|
||||||
|
|
||||||
if (npens <= reader->npens) return 0;
|
|
||||||
|
|
||||||
return hpgs_reader_set_number_of_pens(reader,npens);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SP (Set Pen)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SP (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int pen=0;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&pen)) return -1;
|
|
||||||
|
|
||||||
return hpgs_reader_do_setpen(reader,pen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command PC (Pen Color)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_PC (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int pen=-1;
|
|
||||||
double r=-1.0e20,g=-1.0e20,b=-1.0e20;
|
|
||||||
|
|
||||||
if (!reader->eoc && hpgs_reader_read_int(reader,&pen)) return -1;
|
|
||||||
if (!reader->eoc && hpgs_reader_read_double(reader,&r)) return -1;
|
|
||||||
if (!reader->eoc && hpgs_reader_read_double(reader,&g)) return -1;
|
|
||||||
if (!reader->eoc && hpgs_reader_read_double(reader,&b)) return -1;
|
|
||||||
|
|
||||||
if (pen >= reader->npens)
|
|
||||||
{
|
|
||||||
if (pen < 256)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_set_number_of_pens(reader,pen+1))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("PC: Illegal pen number %d.\n"),pen);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pen < 0)
|
|
||||||
{
|
|
||||||
hpgs_reader_set_std_pen_colors(reader,0,reader->npens);
|
|
||||||
pen = reader->current_pen;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (r==-1.0e20 || g==-1.0e20 || b==-1.0e20)
|
|
||||||
{
|
|
||||||
hpgs_reader_set_std_pen_colors(reader,pen,1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader->pen_colors[pen].r =
|
|
||||||
(r - reader->min_color.r) / (reader->max_color.r - reader->min_color.r);
|
|
||||||
if (reader->pen_colors[pen].r < 0.0) reader->pen_colors[pen].r = 0.0;
|
|
||||||
if (reader->pen_colors[pen].r > 1.0) reader->pen_colors[pen].r = 1.0;
|
|
||||||
|
|
||||||
reader->pen_colors[pen].g =
|
|
||||||
(g - reader->min_color.g) / (reader->max_color.g - reader->min_color.g);
|
|
||||||
if (reader->pen_colors[pen].g < 0.0) reader->pen_colors[pen].g = 0.0;
|
|
||||||
if (reader->pen_colors[pen].g > 1.0) reader->pen_colors[pen].g = 1.0;
|
|
||||||
|
|
||||||
reader->pen_colors[pen].b =
|
|
||||||
(b - reader->min_color.b) / (reader->max_color.b - reader->min_color.b);
|
|
||||||
if (reader->pen_colors[pen].b < 0.0) reader->pen_colors[pen].b = 0.0;
|
|
||||||
if (reader->pen_colors[pen].b > 1.0) reader->pen_colors[pen].b = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pen == reader->current_pen)
|
|
||||||
if (hpgs_setrgbcolor(reader->device,
|
|
||||||
&reader->pen_colors[pen]))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command CR (Color Range)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_CR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->min_color.r = 0.0;
|
|
||||||
reader->min_color.g = 0.0;
|
|
||||||
reader->min_color.b = 0.0;
|
|
||||||
|
|
||||||
reader->max_color.r = 255.0;
|
|
||||||
reader->max_color.g = 255.0;
|
|
||||||
reader->max_color.b = 255.0;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->min_color.r)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->max_color.r)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->min_color.g)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->max_color.g)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->min_color.b)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&reader->max_color.b)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command LA (Line Attributes)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_LA(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int kind;
|
|
||||||
int ivalue;
|
|
||||||
double rvalue;
|
|
||||||
|
|
||||||
static hpgs_line_cap caps[5] =
|
|
||||||
{ hpgs_cap_butt,
|
|
||||||
hpgs_cap_butt,
|
|
||||||
hpgs_cap_square,
|
|
||||||
hpgs_cap_round,
|
|
||||||
hpgs_cap_round };
|
|
||||||
|
|
||||||
static hpgs_line_join joins[7] =
|
|
||||||
{ hpgs_join_miter,
|
|
||||||
hpgs_join_miter,
|
|
||||||
hpgs_join_miter,
|
|
||||||
hpgs_join_miter,
|
|
||||||
hpgs_join_round,
|
|
||||||
hpgs_join_bevel,
|
|
||||||
hpgs_join_miter };
|
|
||||||
|
|
||||||
while (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_int(reader,&kind)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case 3:
|
|
||||||
if (hpgs_reader_read_double(reader,&rvalue)) return -1;
|
|
||||||
if (hpgs_setmiterlimit(reader->device,rvalue)) return -1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (hpgs_reader_read_int(reader,&ivalue)) return -1;
|
|
||||||
if (ivalue >= 0 && ivalue < 5 &&
|
|
||||||
hpgs_setlinecap(reader->device,caps[ivalue])) return -1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (hpgs_reader_read_int(reader,&ivalue)) return -1;
|
|
||||||
if (ivalue >= 0 && ivalue < 7 &&
|
|
||||||
hpgs_setlinejoin(reader->device,joins[ivalue])) return -1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command LT (Line Type)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_LT(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
float dashes[20];
|
|
||||||
int i,ndash;
|
|
||||||
int linetype=0;
|
|
||||||
double patlen = 4.0;
|
|
||||||
int mode = 0;
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&linetype)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_double(reader,&patlen)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&mode)) return -1;
|
|
||||||
|
|
||||||
if (linetype < -8 || linetype > 8)
|
|
||||||
{
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("LT: Illegal linetype %d.\n"),linetype);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// line type are store as percentages.
|
|
||||||
patlen *= 0.01;
|
|
||||||
|
|
||||||
if (mode)
|
|
||||||
patlen *= MM_TO_PT;
|
|
||||||
else
|
|
||||||
patlen *= hypot(reader->P2.x-reader->P1.x,
|
|
||||||
reader->P2.y-reader->P1.y ) * 0.01 * HP_TO_PT;
|
|
||||||
|
|
||||||
ndash = reader->linetype_nsegs[linetype+8];
|
|
||||||
if (ndash > 20) ndash = 20;
|
|
||||||
|
|
||||||
for (i=0;i<ndash;++i)
|
|
||||||
dashes[i] = reader->linetype_segs[linetype+8][i] * patlen;
|
|
||||||
|
|
||||||
return hpgs_setdash(reader->device,
|
|
||||||
dashes,ndash,0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command PW (Pen Width)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_PW (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int pen=-1;
|
|
||||||
double width=1.0;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
if (hpgs_reader_read_double(reader,&width)) return -1;
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_int(reader,&pen)) return -1;
|
|
||||||
|
|
||||||
if (pen < 0 || pen >= reader->npens)
|
|
||||||
{
|
|
||||||
if (pen >= reader->npens && pen < 256)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_set_number_of_pens(reader,pen+1))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("PW: Illegal pen number %d.\n"),pen);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->verbosity >= 2)
|
|
||||||
hpgs_log("PW: pen,width,rel = %d,%g,%d.\n",pen,width,reader->pen_width_relative);
|
|
||||||
|
|
||||||
if (reader->pen_width_relative)
|
|
||||||
width *= 10.0;
|
|
||||||
else
|
|
||||||
width *= MM_TO_PT;
|
|
||||||
|
|
||||||
if (pen < 0)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=0;i<reader->npens;++i)
|
|
||||||
reader->pen_widths[i] = width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reader->pen_widths[pen] = width;
|
|
||||||
|
|
||||||
if (pen < 0 || pen == reader->current_pen)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
if (reader->pen_width_relative)
|
|
||||||
width *= hypot(reader->P2.x-reader->P1.x,
|
|
||||||
reader->P2.y-reader->P1.y ) * 0.001 * HP_TO_PT;
|
|
||||||
else
|
|
||||||
width *= HP_TO_PT / reader->world_scale;
|
|
||||||
|
|
||||||
width *= reader->page_scale;
|
|
||||||
|
|
||||||
if (hpgs_setlinewidth(reader->device,width*reader->lw_factor))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command WU (Width Unit selection)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_WU (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->pen_width_relative=0;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&reader->pen_width_relative)) return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgspjl.c 384 2007-03-18 18:31:15Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the PJL interpreter. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
//#define HPGS_PJL_DEBUG
|
|
||||||
|
|
||||||
static int pjl_read_line (hpgs_reader *reader, char term, char *buf, size_t buf_size)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
while ((reader->last_byte = hpgs_getc(reader->in)) != EOF)
|
|
||||||
{
|
|
||||||
if (i == 0 && reader->last_byte== HPGS_ESC)
|
|
||||||
{
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->last_byte==term)
|
|
||||||
{
|
|
||||||
while ((reader->last_byte = hpgs_getc(reader->in)) != EOF)
|
|
||||||
if (!isspace(reader->last_byte))
|
|
||||||
{
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i > 0 && (buf[i-1]=='\0' || isspace(buf[i-1])))
|
|
||||||
--i;
|
|
||||||
|
|
||||||
if (i<buf_size) buf[i]='\0';
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->last_byte == '\n' && i==4 && strncmp(buf,"@PJL",4)==0)
|
|
||||||
{
|
|
||||||
i=0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->last_byte == '\n') continue;
|
|
||||||
|
|
||||||
if (reader->last_byte != '\r' && i<buf_size)
|
|
||||||
{
|
|
||||||
buf[i] = (i < buf_size-1) ? (char)reader->last_byte : '\0';
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Read a PJL block of the file.
|
|
||||||
|
|
||||||
Return values:
|
|
||||||
\li -1 Error, unexpected EOF.
|
|
||||||
\li 0 Success, ESC found, continue with ESC evaluation.
|
|
||||||
\li 1 Success, return to HPGL context.
|
|
||||||
\li 2 Success, plotsize set, skip interpretation of file.
|
|
||||||
\li 3 Success, go to PCL context.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_PJL(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
char buf[256];
|
|
||||||
int r,arg,arg_sign;
|
|
||||||
int x_size = 0;
|
|
||||||
int y_size = 0;
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
reader->eoc = 0;
|
|
||||||
size_t pos = 0;
|
|
||||||
|
|
||||||
while ((r=pjl_read_line(reader,' ',buf,sizeof(buf))) != EOF)
|
|
||||||
{
|
|
||||||
if (r==-2) return 0; // ESC found.
|
|
||||||
|
|
||||||
// HPGL autodetection.
|
|
||||||
if (pos >= 0 && r>=2 &&
|
|
||||||
buf[0] >= 'A' && buf[0] <= 'Z' &&
|
|
||||||
buf[1] >= 'A' && buf[1] <= 'Z' )
|
|
||||||
{
|
|
||||||
if (hpgs_istream_seek(reader->in,pos))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// overtake PCL papersize, if given.
|
|
||||||
if (x_size > 0 && y_size > 0)
|
|
||||||
{
|
|
||||||
// PJL paper sizes are apparently in PCL units.
|
|
||||||
x_size *= reader->pcl_scale/HP_TO_PT;
|
|
||||||
y_size *= reader->pcl_scale/HP_TO_PT;
|
|
||||||
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Setting PJL papersize %dx%d.\n"),x_size,y_size);
|
|
||||||
|
|
||||||
switch (hpgs_reader_set_plotsize(reader,x_size,y_size))
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
return 2;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return to HPGL context.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(buf,"@PJL"))
|
|
||||||
return hpgs_set_error(hpgs_i18n("Illegal line heading <%s> in PJL."),buf);
|
|
||||||
if (pjl_read_line(reader,' ',buf,sizeof(buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (strcmp(buf,"SET") == 0)
|
|
||||||
{
|
|
||||||
if (pjl_read_line(reader,'=',buf,sizeof(buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (strcmp(buf,"PAPERLENGTH") == 0)
|
|
||||||
{
|
|
||||||
switch (hpgs_reader_read_pcl_int(reader,&arg,&arg_sign))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
return -1;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return hpgs_set_error(hpgs_i18n("Missing number in PJL SET PAPERLENGTH."));
|
|
||||||
}
|
|
||||||
|
|
||||||
x_size = arg;
|
|
||||||
}
|
|
||||||
else if (strcmp(buf,"PAPERWIDTH") == 0)
|
|
||||||
{
|
|
||||||
switch (hpgs_reader_read_pcl_int(reader,&arg,&arg_sign))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
return -1;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return hpgs_set_error(hpgs_i18n("Missing number in PJL SET PAPERWIDTH."));
|
|
||||||
}
|
|
||||||
|
|
||||||
y_size = arg;
|
|
||||||
}
|
|
||||||
else if (strcmp(buf,"RESOLUTION") == 0)
|
|
||||||
{
|
|
||||||
switch (hpgs_reader_read_pcl_int(reader,&arg,&arg_sign))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
return -1;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return hpgs_set_error(hpgs_i18n("Missing number in PJL SET RESOLUTION."));
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->pcl_scale = 72.0/(double)arg;
|
|
||||||
reader->pcl_raster_res = arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp(buf,"ENTER") == 0)
|
|
||||||
{
|
|
||||||
if (pjl_read_line(reader,'=',buf,sizeof(buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (strcmp(buf,"LANGUAGE") == 0)
|
|
||||||
{
|
|
||||||
if (pjl_read_line(reader,'\n',buf,sizeof(buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (x_size > 0 && y_size > 0)
|
|
||||||
{
|
|
||||||
// PJL paper sizes are apparently in PCL units.
|
|
||||||
x_size *= reader->pcl_scale/HP_TO_PT;
|
|
||||||
y_size *= reader->pcl_scale/HP_TO_PT;
|
|
||||||
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Setting PJL papersize %dx%d\n"),x_size,y_size);
|
|
||||||
|
|
||||||
switch (hpgs_reader_set_plotsize(reader,x_size,y_size))
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
return 2;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(buf,"HPGL2") == 0 ||
|
|
||||||
strcmp(buf,"HPGL/2") == 0 ||
|
|
||||||
strcmp(buf,"HP-GL2") == 0 ||
|
|
||||||
strcmp(buf,"HP-GL/2") == 0 )
|
|
||||||
{
|
|
||||||
// probe for escape character
|
|
||||||
if ((reader->last_byte = hpgs_getc(reader->in)) == EOF)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
hpgs_ungetc(reader->last_byte,reader->in);
|
|
||||||
return reader->last_byte == HPGS_ESC ? 0 : 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(buf,"PCL3GUI") == 0 ||
|
|
||||||
strcmp(buf,"PCL3") == 0 ||
|
|
||||||
strcmp(buf,"PCL5") == 0 )
|
|
||||||
return 3;
|
|
||||||
else
|
|
||||||
return hpgs_set_error(hpgs_i18n("Invalid language <%s> in PJL ENTER LANGUAGE."),
|
|
||||||
buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pjl_read_line(reader,'\n',buf,sizeof(buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// store position for HPGL autodetection.
|
|
||||||
if (hpgs_istream_tell(reader->in,&pos))
|
|
||||||
return hpgs_set_error(hpgs_i18n("Cannot get file position in PJL interpretation."));
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsplugin.h 325 2006-04-22 20:01:11Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The extension classes located in my device plugin. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_PLUGIN_H
|
|
||||||
#define __HPGS_PLUGIN_H
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HPGS_SHARED
|
|
||||||
# ifdef WIN32
|
|
||||||
# ifdef __GNUC__
|
|
||||||
# ifdef HPGS_BUILD_PLUGIN
|
|
||||||
# define HPGS_PLUGIN_API __attribute__((dllexport))
|
|
||||||
# else
|
|
||||||
# define HPGS_PLUGIN_API __attribute__((dllimport))
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# ifdef HPGS_BUILD_PLUGIN
|
|
||||||
# define HPGS_PLUGIN_API __declspec(dllexport)
|
|
||||||
# else
|
|
||||||
# define HPGS_PLUGIN_API __declspec(dllimport)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define HPGS_PLUGIN_API
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define HPGS_PLUGIN_API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
HPGS_PLUGIN_API int hpgs_plugin_new_device(hpgs_device **device,
|
|
||||||
void **asset_ctxt,
|
|
||||||
hpgs_reader_asset_func_t *page_asset_func,
|
|
||||||
void **frame_asset_ctxt,
|
|
||||||
hpgs_reader_asset_func_t *frame_asset_func,
|
|
||||||
const char *dev_name,
|
|
||||||
const char *out_fn,
|
|
||||||
const hpgs_bbox *bb,
|
|
||||||
double xres, double yres,
|
|
||||||
hpgs_bool do_rop3,
|
|
||||||
int argc, const char *argv[]);
|
|
||||||
|
|
||||||
HPGS_PLUGIN_API void hpgs_plugin_version(int * major, int *minor);
|
|
||||||
|
|
||||||
HPGS_PLUGIN_API void hpgs_plugin_init();
|
|
||||||
HPGS_PLUGIN_API void hpgs_plugin_cleanup();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // end of extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! __HPGS_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,515 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgsreader.h 381 2007-02-20 09:06:38Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* Private subroutines used by the hpgs_reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#ifndef __HPGS_READER_H__
|
|
||||||
#define __HPGS_READER_H__
|
|
||||||
|
|
||||||
#include <hpgs.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \file hpgsreader.h
|
|
||||||
|
|
||||||
\brief The private interfaces for implementing the HPGL reader.
|
|
||||||
|
|
||||||
A header file, which declares the private structures and functions
|
|
||||||
used to implement the HPGL reader \c hpgs_reader.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HPGS_MAX_PCL_PALETTES 20
|
|
||||||
|
|
||||||
#define MM_TO_PT (72.0 / 25.4)
|
|
||||||
#define HP_TO_PT (72.0 / (25.4 * 40.0))
|
|
||||||
|
|
||||||
#define MAKE_COMMAND(a,b) (((int)(a) << 8) + (b))
|
|
||||||
|
|
||||||
#define AA_CMD MAKE_COMMAND('A','A')
|
|
||||||
#define AC_CMD MAKE_COMMAND('A','C')
|
|
||||||
#define AD_CMD MAKE_COMMAND('A','D')
|
|
||||||
#define AR_CMD MAKE_COMMAND('A','R')
|
|
||||||
#define AT_CMD MAKE_COMMAND('A','T')
|
|
||||||
#define BP_CMD MAKE_COMMAND('B','P')
|
|
||||||
#define BR_CMD MAKE_COMMAND('B','R')
|
|
||||||
#define BZ_CMD MAKE_COMMAND('B','Z')
|
|
||||||
#define CI_CMD MAKE_COMMAND('C','I')
|
|
||||||
#define CO_CMD MAKE_COMMAND('C','O')
|
|
||||||
#define CP_CMD MAKE_COMMAND('C','P')
|
|
||||||
#define CR_CMD MAKE_COMMAND('C','R')
|
|
||||||
#define DI_CMD MAKE_COMMAND('D','I')
|
|
||||||
#define DR_CMD MAKE_COMMAND('D','R')
|
|
||||||
#define DT_CMD MAKE_COMMAND('D','T')
|
|
||||||
#define DV_CMD MAKE_COMMAND('D','V')
|
|
||||||
#define EA_CMD MAKE_COMMAND('E','A')
|
|
||||||
#define EP_CMD MAKE_COMMAND('E','P')
|
|
||||||
#define ER_CMD MAKE_COMMAND('E','R')
|
|
||||||
#define ES_CMD MAKE_COMMAND('E','S')
|
|
||||||
#define EW_CMD MAKE_COMMAND('E','W')
|
|
||||||
#define FP_CMD MAKE_COMMAND('F','P')
|
|
||||||
#define FR_CMD MAKE_COMMAND('F','R')
|
|
||||||
#define FT_CMD MAKE_COMMAND('F','T')
|
|
||||||
#define IN_CMD MAKE_COMMAND('I','N')
|
|
||||||
#define IP_CMD MAKE_COMMAND('I','P')
|
|
||||||
#define IR_CMD MAKE_COMMAND('I','R')
|
|
||||||
#define IW_CMD MAKE_COMMAND('I','W')
|
|
||||||
#define LA_CMD MAKE_COMMAND('L','A')
|
|
||||||
#define LB_CMD MAKE_COMMAND('L','B')
|
|
||||||
#define LO_CMD MAKE_COMMAND('L','O')
|
|
||||||
#define LT_CMD MAKE_COMMAND('L','T')
|
|
||||||
#define MC_CMD MAKE_COMMAND('M','C')
|
|
||||||
#define MG_CMD MAKE_COMMAND('M','G')
|
|
||||||
#define NP_CMD MAKE_COMMAND('N','P')
|
|
||||||
#define PA_CMD MAKE_COMMAND('P','A')
|
|
||||||
#define PC_CMD MAKE_COMMAND('P','C')
|
|
||||||
#define PD_CMD MAKE_COMMAND('P','D')
|
|
||||||
#define PE_CMD MAKE_COMMAND('P','E')
|
|
||||||
#define PG_CMD MAKE_COMMAND('P','G')
|
|
||||||
#define PM_CMD MAKE_COMMAND('P','M')
|
|
||||||
#define PP_CMD MAKE_COMMAND('P','P')
|
|
||||||
#define PR_CMD MAKE_COMMAND('P','R')
|
|
||||||
#define PS_CMD MAKE_COMMAND('P','S')
|
|
||||||
#define PU_CMD MAKE_COMMAND('P','U')
|
|
||||||
#define PW_CMD MAKE_COMMAND('P','W')
|
|
||||||
#define RA_CMD MAKE_COMMAND('R','A')
|
|
||||||
#define RO_CMD MAKE_COMMAND('R','O')
|
|
||||||
#define RR_CMD MAKE_COMMAND('R','R')
|
|
||||||
#define RT_CMD MAKE_COMMAND('R','T')
|
|
||||||
#define SA_CMD MAKE_COMMAND('S','A')
|
|
||||||
#define SC_CMD MAKE_COMMAND('S','C')
|
|
||||||
#define SD_CMD MAKE_COMMAND('S','D')
|
|
||||||
#define SI_CMD MAKE_COMMAND('S','I')
|
|
||||||
#define SL_CMD MAKE_COMMAND('S','L')
|
|
||||||
#define SM_CMD MAKE_COMMAND('S','M')
|
|
||||||
#define SP_CMD MAKE_COMMAND('S','P')
|
|
||||||
#define SR_CMD MAKE_COMMAND('S','R')
|
|
||||||
#define SS_CMD MAKE_COMMAND('S','S')
|
|
||||||
#define TR_CMD MAKE_COMMAND('T','R')
|
|
||||||
#define UL_CMD MAKE_COMMAND('U','L')
|
|
||||||
#define WG_CMD MAKE_COMMAND('W','G')
|
|
||||||
#define WU_CMD MAKE_COMMAND('W','U')
|
|
||||||
|
|
||||||
/*! @addtogroup reader
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct hpgs_reader_poly_point_st hpgs_reader_poly_point;
|
|
||||||
|
|
||||||
/*! \brief A point in hte HPGL polygon buffer
|
|
||||||
|
|
||||||
This structure holds a point in the polygon buffer of HPGL
|
|
||||||
used to implement PM, EP and FP commands.
|
|
||||||
*/
|
|
||||||
struct hpgs_reader_poly_point_st
|
|
||||||
{
|
|
||||||
hpgs_point p; //!< The coordinates of the point
|
|
||||||
int flag; //!< 0 moveto, 1 lineto, 2 curveto
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct hpgs_reader_pcl_palette_st hpgs_reader_pcl_palette;
|
|
||||||
|
|
||||||
/*! \brief A PCL palette as used by PCL push/pop palette.
|
|
||||||
|
|
||||||
This structure holds all properties which are saved/resoterd through PCL push/pop palette.
|
|
||||||
*/
|
|
||||||
struct hpgs_reader_pcl_palette_st
|
|
||||||
{
|
|
||||||
hpgs_palette_color colors[256]; /*!< The palette colors. */
|
|
||||||
hpgs_palette_color last_color; /*!< The PCL color currently being assembled. */
|
|
||||||
|
|
||||||
int cid_space; /*!< The current PCL color space. */
|
|
||||||
int cid_enc; /*!< The current PCL pixel encoding scheme. */
|
|
||||||
int cid_bpi; /*!< PCL Bits per color index. */
|
|
||||||
int cid_bpc[3];/*!< PCL Bits per color component. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief A HPGL interpreter.
|
|
||||||
|
|
||||||
This structure holds all the states used during the interpretation
|
|
||||||
of a HPGL stream. Users of the library usually don't have to cope
|
|
||||||
with details of this structure.
|
|
||||||
*/
|
|
||||||
struct hpgs_reader_st
|
|
||||||
{
|
|
||||||
hpgs_istream *in; /*!< The current input stream. */
|
|
||||||
hpgs_device *device; /*!< The current output device. */
|
|
||||||
hpgs_device *plotsize_device; /*!< The current plotsize device. */
|
|
||||||
|
|
||||||
int current_page; /*!< The number of the current page. -1...single page mode. */
|
|
||||||
|
|
||||||
int verbosity; /*!< The verbosity level in effect. */
|
|
||||||
|
|
||||||
double lw_factor; /*!< The linewidth scaling factor. */
|
|
||||||
/*@{ */
|
|
||||||
/*! The paper size in PostScript pt (1/72 inch). */
|
|
||||||
double x_size,y_size; /*@} */
|
|
||||||
/*@{ */
|
|
||||||
/*! The frame advance vector in PostScript pt (1/72 inch). */
|
|
||||||
double frame_x,frame_y; /*@} */
|
|
||||||
hpgs_point P1; /*!< HPGL frame point P1 in PostScript pt (1/72 inch). */
|
|
||||||
hpgs_point P2; /*!< HPGL frame point P2 in PostScript pt (1/72 inch). */
|
|
||||||
hpgs_point delta_P; /*!< The difference of P2-P1 as set by the IP command. */
|
|
||||||
int rotation; /*!< The current rotation angle (90/180/270/360). */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! The current effective coordinate scaling of a SC command. */
|
|
||||||
int sc_type;
|
|
||||||
double sc_xmin;
|
|
||||||
double sc_xmax;
|
|
||||||
double sc_ymin;
|
|
||||||
double sc_ymax;
|
|
||||||
double sc_left;
|
|
||||||
double sc_bottom;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
int rop3; /*!< ROP3 operation in effect. */
|
|
||||||
hpgs_bool src_transparency; /*!< ROP3 source transparency. */
|
|
||||||
hpgs_bool pattern_transparency; /*!< ROP3 pattern transparency. */
|
|
||||||
|
|
||||||
hpgs_matrix world_matrix; /*!< transformation matrix for the transformation of HPGL to PostScript
|
|
||||||
(world) coordinates usually given in points (1/72 inch). */
|
|
||||||
|
|
||||||
double world_scale; /*!< sqrt(|det(world_matrix)|) */
|
|
||||||
|
|
||||||
hpgs_matrix page_matrix; /*!< transformation matrix for the transformation of
|
|
||||||
PostScript (world) coordinates usually given in points (1/72 inch)
|
|
||||||
to user defined page-coorindates. */
|
|
||||||
|
|
||||||
double page_scale; /*!< sqrt(|det(page_matrix)|) */
|
|
||||||
|
|
||||||
hpgs_matrix total_matrix; /*!< The concatenation of page_matrix and world_matrix. */
|
|
||||||
|
|
||||||
double total_scale; /*!< sqrt(|det(page_matrix)|) */
|
|
||||||
|
|
||||||
int page_mode; /*!< 0...untransformed, 1...fixed page, 2...dynamic page */
|
|
||||||
|
|
||||||
double page_width; /*!< The page width or the maximal page width in points. */
|
|
||||||
double page_height; /*!< The page height or the maximal page height in points. */
|
|
||||||
double page_angle; /*!< The rotation angle of the HPGL content on the page. */
|
|
||||||
double page_border; /*!< The border of the HPGL border on the page. */
|
|
||||||
|
|
||||||
hpgs_bbox page_bbox; /*!< The currently active page bounding box. */
|
|
||||||
hpgs_bbox content_bbox; /*!< The bounding box of the HPGL content of the current page. */
|
|
||||||
|
|
||||||
void *page_asset_ctxt; /*!< A callback for rendering additional page assets before showpage. */
|
|
||||||
hpgs_reader_asset_func_t page_asset_func; /*!< A callback for rendering additional page assets before showpage. */
|
|
||||||
|
|
||||||
void *frame_asset_ctxt; /*!< A callback for rendering additional frame assets before frame advance/showpage. */
|
|
||||||
hpgs_reader_asset_func_t frame_asset_func; /*!< A callback for rendering additional frame asset before frame advance/showpage. */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! linetype settings. (-8,...8) stored from 0...16 */
|
|
||||||
int linetype_nsegs[17];
|
|
||||||
float linetype_segs[17][20];
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! pen settings */
|
|
||||||
int npens;
|
|
||||||
double *pen_widths;
|
|
||||||
hpgs_color *pen_colors;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
hpgs_color min_color; /*!< The minimal RGB values. */
|
|
||||||
hpgs_color max_color; /*!< The maximal RGB values. */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! label terminator settings */
|
|
||||||
char label_term;
|
|
||||||
int label_term_ignore;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
int polygon_mode; /*!< Are we in polygon mode? */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! the polygon buffer used in polygon mode. */
|
|
||||||
hpgs_reader_poly_point *poly_buffer;
|
|
||||||
int poly_buffer_size;
|
|
||||||
int poly_buffer_alloc_size;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
int polygon_open; /*!< Is a polygon currently open? */
|
|
||||||
int pen_width_relative; /*!< Are pen widths specified relative? */
|
|
||||||
int pen_down; /*!< Is the pen down? */
|
|
||||||
int current_pen; /*!< Number of the current pen. */
|
|
||||||
int current_linetype; /*!< Number of the current linetype. */
|
|
||||||
int absolute_plotting; /*!< Are PU and PD coordinates absoulte, because a PA statement is in effect? */
|
|
||||||
int have_current_point; /*!< Do we have a current pen position, aka current_point is a valid position. */
|
|
||||||
hpgs_point current_point; /*!< The current pen position in PostScript pt (1/72 inch),
|
|
||||||
if \c have_current_point is true. */
|
|
||||||
hpgs_point first_path_point;/*!< The first point in a path, if \c polygon_open is true. */
|
|
||||||
hpgs_point min_path_point; /*!< The minimal x/y coordinates of all points in an open path. */
|
|
||||||
hpgs_point max_path_point; /*!< The maximal x/y coordinates of all points in an open path. */
|
|
||||||
hpgs_point anchor_point; /*!< The anchor point for fill patterns. */
|
|
||||||
|
|
||||||
int current_ft; /*!< The fill type currently in effect. */
|
|
||||||
double ft3_angle; /*!< The current pattern angle of fill type 3. */
|
|
||||||
double ft3_spacing;/*!< The current pattern spacing of fill type 3. */
|
|
||||||
double ft4_angle; /*!< The current pattern angle of fill type 4. */
|
|
||||||
double ft4_spacing;/*!< The current pattern spacing of fill type 4. */
|
|
||||||
double ft10_level; /*!< The current color level for fill type 10. */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! the text state for the standard font. */
|
|
||||||
int default_encoding;
|
|
||||||
int default_face;
|
|
||||||
int default_spacing;
|
|
||||||
double default_pitch;
|
|
||||||
double default_height;
|
|
||||||
int default_posture;
|
|
||||||
int default_weight;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! the text state for the alternate font. */
|
|
||||||
int alternate_encoding;
|
|
||||||
int alternate_face;
|
|
||||||
int alternate_spacing;
|
|
||||||
double alternate_pitch;
|
|
||||||
double alternate_height;
|
|
||||||
int alternate_posture;
|
|
||||||
int alternate_weight;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
int alternate_font; /*!< do we use the alternate font? */
|
|
||||||
|
|
||||||
/*@{ */
|
|
||||||
/*! text attributes set through special commands. */
|
|
||||||
hpgs_point cr_point;
|
|
||||||
hpgs_point current_char_size;
|
|
||||||
hpgs_point current_extra_space;
|
|
||||||
double current_slant;
|
|
||||||
int current_label_origin;
|
|
||||||
int current_text_path;
|
|
||||||
int current_text_line;
|
|
||||||
double current_label_angle;
|
|
||||||
/*@} */
|
|
||||||
|
|
||||||
double pcl_scale; /*!< The factor from PCL units to PostScript pt (1/72 inch). */
|
|
||||||
double pcl_hmi; /*!< PCL horizontal motion index in pt. */
|
|
||||||
double pcl_vmi; /*!< PCL vertical motion index in pt. */
|
|
||||||
hpgs_point pcl_point; /*!< PCL point position in pt. */
|
|
||||||
|
|
||||||
hpgs_reader_pcl_palette *pcl_palettes[HPGS_MAX_PCL_PALETTES]; /*!< The PCL palette stack of palattes fo 256 colors .*/
|
|
||||||
int pcl_i_palette; /*!< The number of of the current PCL palette on the stack. */
|
|
||||||
|
|
||||||
int pcl_raster_mode; /*!< The PCL ratser mode.
|
|
||||||
-1 no raster graphics, 0 horizontal graphics, 3 vertical graphics */
|
|
||||||
int pcl_raster_presentation;/*!< The PCL raster presentation mode. */
|
|
||||||
int pcl_raster_src_width; /*!< The PCL raster image source width. */
|
|
||||||
int pcl_raster_src_height; /*!< The PCL raster image source height. */
|
|
||||||
int pcl_raster_dest_width; /*!< The PCL raster image destination width. */
|
|
||||||
int pcl_raster_dest_height; /*!< The PCL raster image destination height. */
|
|
||||||
int pcl_raster_res; /*!< The PCL raster image resolution. */
|
|
||||||
int pcl_raster_compression; /*!< The PCL raster compression in effect. */
|
|
||||||
int pcl_raster_y_offset; /*!< The PCL raster y offset in effect. */
|
|
||||||
int pcl_raster_plane; /*!< The current PCL raster plane for transfer data by plane. */
|
|
||||||
int pcl_raster_line; /*!< The number of the raster line currently transferred. */
|
|
||||||
|
|
||||||
unsigned char *pcl_raster_data[8];/*!< The buffer for the data of the current raster. One pointer per plane. */
|
|
||||||
int pcl_raster_data_size; /*!< The size of the raster data buffer. */
|
|
||||||
int pcl_raster_planes; /*!< The number of planes of the raster data currently being transferred. */
|
|
||||||
|
|
||||||
|
|
||||||
hpgs_image *pcl_image; /*!< The image currently filled by pcl. */
|
|
||||||
|
|
||||||
// The filename for dumped pcl images.
|
|
||||||
int png_dump_count; /*!< The number of PCL images dumped so far. */
|
|
||||||
char *png_dump_filename; /*!< The base filename for dumped PCL images. */
|
|
||||||
|
|
||||||
int clipsave_depth; /*!< how many clipsaves have been issued? */
|
|
||||||
|
|
||||||
int last_byte; /*!< The last byte extracted from the stream? */
|
|
||||||
int bytes_ignored;/*!< A byte counter for various purposes. */
|
|
||||||
int eoc; /*!< Did we reach the end of a HPGL command? */
|
|
||||||
hpgs_bool interrupted; /*!< Did someone call \c hpgs_reader_interrupt ? */
|
|
||||||
};
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_check_param_end(hpgs_reader *reader);
|
|
||||||
|
|
||||||
/*! read an integer argument from the stream - PCL version.
|
|
||||||
return values:
|
|
||||||
\li -1 read error/EOF
|
|
||||||
\li 0 no integer found.
|
|
||||||
\li 1 integer found.
|
|
||||||
*/
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_pcl_int(hpgs_reader *reader, int *x, int *sign);
|
|
||||||
|
|
||||||
/*! read an integer argument from the stream .
|
|
||||||
return values:
|
|
||||||
\li -1 read error/EOF
|
|
||||||
\li 0 success.
|
|
||||||
\li 1 End of command.
|
|
||||||
*/
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_int(hpgs_reader *reader, int *x);
|
|
||||||
|
|
||||||
/*" read a double argument from the stream.
|
|
||||||
return values:
|
|
||||||
\li -1 read error/EOF
|
|
||||||
\li 0 success.
|
|
||||||
\li 1 End of command.
|
|
||||||
*/
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_double(hpgs_reader *reader, double *x);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_point(hpgs_reader *reader, hpgs_point *p, int xform);
|
|
||||||
|
|
||||||
/* read a new string argument from the stream
|
|
||||||
return values:
|
|
||||||
\li -1 read error/EOF
|
|
||||||
\li 0 success.
|
|
||||||
\li 1 End of command.
|
|
||||||
*/
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_new_string(hpgs_reader *reader, char *str);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_read_label_string(hpgs_reader *reader, char *str);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_reader_set_page_matrix (hpgs_reader *reader, const hpgs_bbox *bb);
|
|
||||||
HPGS_INTERNAL_API void hpgs_reader_set_default_transformation (hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API void hpgs_reader_set_default_state (hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API void hpgs_reader_set_defaults (hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_set_plotsize (hpgs_reader *reader, double xs, double ys);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_showpage (hpgs_reader *reader, int ipage);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API void hpgs_reader_set_std_pen_colors(hpgs_reader *reader,
|
|
||||||
int i0, int n);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_checkpath(hpgs_reader *reader);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_moveto(hpgs_reader *reader, hpgs_point *p);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_lineto(hpgs_reader *reader, hpgs_point *p);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_curveto(hpgs_reader *reader,
|
|
||||||
hpgs_point *p1, hpgs_point *p2, hpgs_point *p3);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_stroke(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_fill(hpgs_reader *reader, hpgs_bool winding);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_closepath(hpgs_reader *reader);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_setpen(hpgs_reader *reader, int pen);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_label(hpgs_reader *reader,
|
|
||||||
const char *str, int str_len,
|
|
||||||
int face,
|
|
||||||
int encoding,
|
|
||||||
int posture,
|
|
||||||
int weight,
|
|
||||||
const hpgs_point *left_vec,
|
|
||||||
const hpgs_point *up_vec,
|
|
||||||
const hpgs_point *space_vec);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_device_label(hpgs_device *dev,
|
|
||||||
hpgs_point *pos,
|
|
||||||
const char *str, int str_len,
|
|
||||||
int face,
|
|
||||||
const char *encoding,
|
|
||||||
int posture,
|
|
||||||
int weight,
|
|
||||||
const hpgs_point *left_vec,
|
|
||||||
const hpgs_point *up_vec,
|
|
||||||
const hpgs_point *space_vec);
|
|
||||||
|
|
||||||
typedef int (*hpgs_reader_hpglcmd_func_t)(hpgs_reader *reader);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PCL(hpgs_reader *reader, hpgs_bool take_pos);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PJL(hpgs_reader *reader);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_push_pcl_palette (hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_pop_pcl_palette (hpgs_reader *reader);
|
|
||||||
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_AA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_AC(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_AD(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_AR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_AT(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_BP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_BR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_BZ(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_CI(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_CO(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_CP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_CR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_DI(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_DR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_DT(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_DV(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_EA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_EP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_ER(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_ES(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_EW(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_FP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_FR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_FT(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_IN(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_IP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_IR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_IW(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_LA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_LB(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_LO(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_LT(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_MC(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_MG(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_NP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PC(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PD(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PE(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PG(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PM(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PS(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PU(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_PW(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_RA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_RO(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_RR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_RT(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SA(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SC(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SD(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SI(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SL(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SM(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SP(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_SS(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_TR(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_UL(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_WG(hpgs_reader *reader);
|
|
||||||
HPGS_INTERNAL_API int hpgs_reader_do_WU(hpgs_reader *reader);
|
|
||||||
|
|
||||||
/*! @} */ /* end of group reader */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // end of extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ! __HPGS_READER_H__
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,627 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgssetup.c 362 2006-10-16 14:13:48Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
Standard values.
|
|
||||||
*/
|
|
||||||
static hpgs_color std_pen_colors[8] =
|
|
||||||
{
|
|
||||||
{ 1.0, 1.0, 1.0 },
|
|
||||||
{ 0.0, 0.0, 0.0 },
|
|
||||||
{ 1.0, 0.0, 0.0 },
|
|
||||||
{ 0.0, 1.0, 0.0 },
|
|
||||||
{ 1.0, 1.0, 0.0 },
|
|
||||||
{ 0.0, 0.0, 1.0 },
|
|
||||||
{ 1.0, 0.0, 1.0 },
|
|
||||||
{ 0.0, 1.0, 1.0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static double std_pen_widths[8] =
|
|
||||||
{
|
|
||||||
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
|
|
||||||
};
|
|
||||||
|
|
||||||
static int std_linetype_nsegs[17] =
|
|
||||||
{
|
|
||||||
9, 7, 7, 5, 5, 3, 3, 3, 0, 2, 2, 2, 4, 4, 6, 6, 8
|
|
||||||
};
|
|
||||||
|
|
||||||
static float std_linetype_segs[17][20] =
|
|
||||||
{
|
|
||||||
{24, 10, 1, 10, 10, 10, 1, 10, 24, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{34, 10, 1, 10, 1, 10, 34, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{25, 10, 10, 10, 10, 10, 25, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{35, 10, 10, 10, 35, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{40, 10, 1, 10, 39, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{35, 30, 35, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{25, 50, 25, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{ 1, 99, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{ 1, 99, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{50, 50, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{70, 30, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{79, 10, 1, 10, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{70, 10, 10, 10, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{50, 10, 10, 10, 10, 10, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{68, 10, 1, 10, 1, 10, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{48, 10, 1, 10, 10, 10, 1, 10, 0, 0,0,0,0,0,0,0,0,0,0,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void hpgs_reader_set_default_state (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
reader->frame_x=0.0;
|
|
||||||
reader->frame_y=0.0;
|
|
||||||
|
|
||||||
reader->x_size = 47520.0 * HP_TO_PT;
|
|
||||||
reader->y_size = 33600.0 * HP_TO_PT;
|
|
||||||
|
|
||||||
reader->P1.x = 0.0;
|
|
||||||
reader->P1.y = 0.0;
|
|
||||||
reader->P2.x = reader->x_size;
|
|
||||||
reader->P2.y = reader->y_size;
|
|
||||||
reader->delta_P.x = reader->P2.x - reader->P1.x;
|
|
||||||
reader->delta_P.y = reader->P2.y - reader->P1.y;
|
|
||||||
|
|
||||||
reader->rotation=0;
|
|
||||||
|
|
||||||
reader->sc_type=-1;
|
|
||||||
reader->sc_xmin=0.0;
|
|
||||||
reader->sc_xmax=1.0;
|
|
||||||
reader->sc_ymin=0.0;
|
|
||||||
reader->sc_ymax=1.0;
|
|
||||||
reader->sc_left = 50.0;
|
|
||||||
reader->sc_bottom = 50.0;
|
|
||||||
|
|
||||||
hpgs_reader_set_default_transformation (reader);
|
|
||||||
|
|
||||||
reader->rop3 = 252;
|
|
||||||
reader->src_transparency = HPGS_TRUE;
|
|
||||||
reader->pattern_transparency = HPGS_TRUE;
|
|
||||||
|
|
||||||
reader->pen_down = 0;
|
|
||||||
reader->pen_width_relative = 0;
|
|
||||||
|
|
||||||
reader->label_term= '\003';
|
|
||||||
reader->label_term_ignore = 1;
|
|
||||||
reader->polygon_mode = 0;
|
|
||||||
reader->poly_buffer_size = 0;
|
|
||||||
reader->polygon_open = 0;
|
|
||||||
reader->have_current_point = 0;
|
|
||||||
reader->current_point.x = reader->page_matrix.dx;
|
|
||||||
reader->current_point.y = reader->page_matrix.dy;
|
|
||||||
reader->current_pen = 0;
|
|
||||||
reader->current_linetype = 0;
|
|
||||||
reader->absolute_plotting = 1;
|
|
||||||
reader->anchor_point.x = 0.0;
|
|
||||||
reader->anchor_point.y = 0.0;
|
|
||||||
|
|
||||||
reader->current_ft = 1;
|
|
||||||
reader->ft3_angle = 0.0;
|
|
||||||
reader->ft3_spacing = 0.0;
|
|
||||||
reader->ft4_angle = 0.0;
|
|
||||||
reader->ft4_spacing = 0.0;
|
|
||||||
reader->ft10_level = 100.0;
|
|
||||||
|
|
||||||
reader->default_encoding = 0;
|
|
||||||
reader->default_face = 0;
|
|
||||||
reader->default_spacing = 0;
|
|
||||||
reader->default_pitch = 9.0;
|
|
||||||
reader->default_height = 11.5;
|
|
||||||
reader->default_posture = 0;
|
|
||||||
reader->default_weight = 0;
|
|
||||||
|
|
||||||
reader->alternate_encoding = 0;
|
|
||||||
reader->alternate_face = 0;
|
|
||||||
reader->alternate_spacing = 0;
|
|
||||||
reader->alternate_pitch = 9.0;
|
|
||||||
reader->alternate_height = 11.5;
|
|
||||||
reader->alternate_posture = 0;
|
|
||||||
reader->alternate_weight = 0;
|
|
||||||
|
|
||||||
reader->alternate_font = 0;
|
|
||||||
reader->cr_point = reader->current_point;
|
|
||||||
reader->current_char_size.x = 0.0;
|
|
||||||
reader->current_char_size.y = 0.0;
|
|
||||||
reader->current_extra_space.x = 0.0;
|
|
||||||
reader->current_extra_space.y = 0.0;
|
|
||||||
reader->current_slant = 0.0;
|
|
||||||
reader->current_label_origin = 1;
|
|
||||||
reader->current_text_path = 0;
|
|
||||||
reader->current_text_line = 0;
|
|
||||||
reader->current_label_angle = 0.0;
|
|
||||||
|
|
||||||
// standard linetypes. (-8,...8)
|
|
||||||
memcpy(reader->linetype_nsegs,std_linetype_nsegs,sizeof(std_linetype_nsegs));
|
|
||||||
memcpy(reader->linetype_segs,std_linetype_segs,sizeof(std_linetype_segs));
|
|
||||||
}
|
|
||||||
|
|
||||||
void hpgs_reader_set_std_pen_colors(hpgs_reader *reader,
|
|
||||||
int i0, int n)
|
|
||||||
{
|
|
||||||
int n_std = sizeof(std_pen_colors)/sizeof(hpgs_color);
|
|
||||||
|
|
||||||
if (i0 >= n_std) return;
|
|
||||||
if (n <= 0) return;
|
|
||||||
if (i0+n >= n_std) n = n_std-i0;
|
|
||||||
|
|
||||||
memcpy(reader->pen_colors+i0,std_pen_colors+i0,sizeof(hpgs_color)*n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_reader_pcl_palette *hpgs_reader_new_pcl_palette ()
|
|
||||||
{
|
|
||||||
hpgs_reader_pcl_palette *ret=(hpgs_reader_pcl_palette *)malloc(sizeof(hpgs_reader_pcl_palette));
|
|
||||||
|
|
||||||
if (!ret) return 0;
|
|
||||||
|
|
||||||
memset(ret->colors,0,sizeof(hpgs_palette_color)*256);
|
|
||||||
ret->colors[0].r = 0xff;
|
|
||||||
ret->colors[0].g = 0xff;
|
|
||||||
ret->colors[0].b = 0xff;
|
|
||||||
|
|
||||||
ret->last_color.r = 0;
|
|
||||||
ret->last_color.g = 0;
|
|
||||||
ret->last_color.b = 0;
|
|
||||||
|
|
||||||
ret->cid_space = 0;
|
|
||||||
ret->cid_enc = 1;
|
|
||||||
ret->cid_bpi = 1;
|
|
||||||
ret->cid_bpc[0] = 8;
|
|
||||||
ret->cid_bpc[1] = 8;
|
|
||||||
ret->cid_bpc[2] = 8;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_reader_pcl_palette *hpgs_reader_dup_pcl_palette (const hpgs_reader_pcl_palette *p)
|
|
||||||
{
|
|
||||||
hpgs_reader_pcl_palette *ret=(hpgs_reader_pcl_palette *)malloc(sizeof(hpgs_reader_pcl_palette));
|
|
||||||
|
|
||||||
if (!ret) return 0;
|
|
||||||
|
|
||||||
memcpy(ret,p,sizeof(hpgs_reader_pcl_palette));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hpgs_reader_destroy_pcl_palette (hpgs_reader_pcl_palette *p)
|
|
||||||
{
|
|
||||||
if (p)
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_reader_push_pcl_palette (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
if (reader->pcl_i_palette >= HPGS_MAX_PCL_PALETTES-1)
|
|
||||||
return hpgs_set_error(hpgs_i18n("PCL palette stack overflow (maximal stack size = %d)."),
|
|
||||||
HPGS_MAX_PCL_PALETTES);
|
|
||||||
|
|
||||||
|
|
||||||
if (reader->pcl_i_palette >= 0)
|
|
||||||
reader->pcl_palettes[reader->pcl_i_palette+1] =
|
|
||||||
hpgs_reader_dup_pcl_palette (reader->pcl_palettes[reader->pcl_i_palette]);
|
|
||||||
else
|
|
||||||
reader->pcl_palettes[reader->pcl_i_palette+1] =
|
|
||||||
hpgs_reader_new_pcl_palette ();
|
|
||||||
|
|
||||||
if (!reader->pcl_palettes[reader->pcl_i_palette+1])
|
|
||||||
return hpgs_set_error(hpgs_i18n("Out of memory pushing PCL palette."));
|
|
||||||
|
|
||||||
++reader->pcl_i_palette;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hpgs_reader_pop_pcl_palette (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
if (reader->pcl_i_palette <= 0)
|
|
||||||
return hpgs_set_error(hpgs_i18n("PCL palette stack underflow."));
|
|
||||||
|
|
||||||
hpgs_reader_destroy_pcl_palette(reader->pcl_palettes[reader->pcl_i_palette]);
|
|
||||||
|
|
||||||
--reader->pcl_i_palette;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hpgs_reader_set_defaults (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (reader->pen_widths)
|
|
||||||
free(reader->pen_widths);
|
|
||||||
|
|
||||||
if (reader->pen_colors)
|
|
||||||
free(reader->pen_colors);
|
|
||||||
|
|
||||||
if (reader->poly_buffer)
|
|
||||||
free(reader->poly_buffer);
|
|
||||||
|
|
||||||
// standard pen widths.
|
|
||||||
reader->npens = 8;
|
|
||||||
|
|
||||||
reader->pen_widths = (double*)malloc(sizeof(std_pen_widths));
|
|
||||||
memcpy(reader->pen_widths,std_pen_widths,sizeof(std_pen_widths));
|
|
||||||
|
|
||||||
reader->pen_colors = (hpgs_color *)malloc(sizeof(std_pen_colors));
|
|
||||||
memcpy(reader->pen_colors,std_pen_colors,sizeof(std_pen_colors));
|
|
||||||
|
|
||||||
reader->min_color.r=0.0;
|
|
||||||
reader->min_color.g=0.0;
|
|
||||||
reader->min_color.b=0.0;
|
|
||||||
|
|
||||||
reader->max_color.r=255.0;
|
|
||||||
reader->max_color.g=255.0;
|
|
||||||
reader->max_color.b=255.0;
|
|
||||||
|
|
||||||
reader->poly_buffer_alloc_size = 256;
|
|
||||||
reader->poly_buffer_size = 0;
|
|
||||||
|
|
||||||
reader->poly_buffer = (hpgs_reader_poly_point *)
|
|
||||||
malloc(sizeof(hpgs_reader_poly_point)*reader->poly_buffer_alloc_size);
|
|
||||||
|
|
||||||
hpgs_reader_set_default_state (reader);
|
|
||||||
|
|
||||||
reader->clipsave_depth = 0;
|
|
||||||
|
|
||||||
for (i=0;i<=reader->pcl_i_palette;++i)
|
|
||||||
hpgs_reader_destroy_pcl_palette(reader->pcl_palettes[i]);
|
|
||||||
|
|
||||||
reader->pcl_i_palette = -1;
|
|
||||||
|
|
||||||
hpgs_reader_push_pcl_palette(reader);
|
|
||||||
|
|
||||||
for (i=0;i<8;++i)
|
|
||||||
if (reader->pcl_raster_data[i])
|
|
||||||
{
|
|
||||||
free(reader->pcl_raster_data[i]);
|
|
||||||
reader->pcl_raster_data[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->pcl_image)
|
|
||||||
hpgs_image_destroy(reader->pcl_image);
|
|
||||||
|
|
||||||
reader->pcl_scale = 72.0/300.0;
|
|
||||||
reader->pcl_hmi = 7.2;
|
|
||||||
reader->pcl_vmi = 12.0;
|
|
||||||
reader->pcl_point.x = 0.0;
|
|
||||||
reader->pcl_point.y = 0.0;
|
|
||||||
|
|
||||||
reader->pcl_raster_mode = -1;
|
|
||||||
reader->pcl_raster_presentation = 0;
|
|
||||||
reader->pcl_raster_src_width = 0;
|
|
||||||
reader->pcl_raster_src_height = 0;
|
|
||||||
reader->pcl_raster_dest_width = 0;
|
|
||||||
reader->pcl_raster_dest_height = 0;
|
|
||||||
reader->pcl_raster_res = 75;
|
|
||||||
reader->pcl_raster_compression = 0;
|
|
||||||
reader->pcl_raster_y_offset = 0;
|
|
||||||
reader->pcl_raster_plane = 0;
|
|
||||||
reader->pcl_raster_line = 0;
|
|
||||||
|
|
||||||
reader->pcl_raster_data_size = 0;
|
|
||||||
reader->pcl_raster_planes = 1;
|
|
||||||
|
|
||||||
reader->pcl_image=0;
|
|
||||||
|
|
||||||
reader->bytes_ignored = 0;
|
|
||||||
reader->eoc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initializes the device */
|
|
||||||
static int init_device(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
hpgs_color pat = { 0.0,0.0,0.0 };
|
|
||||||
|
|
||||||
reader->rop3 = 252;
|
|
||||||
reader->src_transparency = HPGS_TRUE;
|
|
||||||
reader->pattern_transparency = HPGS_TRUE;
|
|
||||||
|
|
||||||
if (hpgs_setlinejoin(reader->device,hpgs_join_miter)) return -1;
|
|
||||||
if (hpgs_setlinecap(reader->device,hpgs_cap_butt)) return -1;
|
|
||||||
if (hpgs_setmiterlimit(reader->device,5.0)) return -1;
|
|
||||||
if (hpgs_setrop3(reader->device,
|
|
||||||
reader->rop3,
|
|
||||||
reader->src_transparency,
|
|
||||||
reader->pattern_transparency)) return -1;
|
|
||||||
if (hpgs_setpatcol(reader->device,&pat)) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command BP (Begin Plot)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_BP (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
while (!reader->eoc)
|
|
||||||
{
|
|
||||||
int kind;
|
|
||||||
int dummy;
|
|
||||||
char header[HPGS_MAX_LABEL_SIZE];
|
|
||||||
if (hpgs_reader_read_int(reader,&kind)) return -1;
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (hpgs_reader_read_new_string(reader,header)) return -1;
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Plot Title: %.*s\n"),HPGS_MAX_LABEL_SIZE,header);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
if (hpgs_reader_read_int(reader,&dummy)) return -1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return init_device(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command CO (COmment)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_CO (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
char comment[HPGS_MAX_LABEL_SIZE];
|
|
||||||
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_new_string(reader,comment)) return -1;
|
|
||||||
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Comment: %.*s\n"),HPGS_MAX_LABEL_SIZE,comment);
|
|
||||||
|
|
||||||
return reader->eoc ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command IN (Initialize Plot)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_IN (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
int dummy;
|
|
||||||
if (hpgs_reader_read_int(reader,&dummy)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (reader->clipsave_depth > 0)
|
|
||||||
{
|
|
||||||
hpgs_cliprestore(reader->device);
|
|
||||||
--reader->clipsave_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
hpgs_reader_set_default_state (reader);
|
|
||||||
|
|
||||||
for (i=0;i<reader->npens;++i)
|
|
||||||
reader->pen_widths[i] = 1.0;
|
|
||||||
|
|
||||||
return init_device(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Internal function, which calls the page asset callback and
|
|
||||||
does a showpage on the device.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_showpage (hpgs_reader *reader, int ipage)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
while (reader->clipsave_depth > 0)
|
|
||||||
{
|
|
||||||
hpgs_cliprestore(reader->device);
|
|
||||||
--reader->clipsave_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->frame_asset_func)
|
|
||||||
{
|
|
||||||
hpgs_bbox frame_bbox;
|
|
||||||
|
|
||||||
frame_bbox.llx = reader->frame_x == 0.0 ? reader->content_bbox.llx : reader->frame_x;
|
|
||||||
frame_bbox.lly = reader->content_bbox.lly;
|
|
||||||
frame_bbox.urx = reader->content_bbox.urx;
|
|
||||||
frame_bbox.ury = reader->content_bbox.ury;
|
|
||||||
|
|
||||||
if (frame_bbox.urx > frame_bbox.llx)
|
|
||||||
{
|
|
||||||
int ipage = reader->current_page;
|
|
||||||
|
|
||||||
if (reader->frame_asset_func(reader->frame_asset_ctxt,
|
|
||||||
reader->device,
|
|
||||||
&reader->page_matrix,
|
|
||||||
&reader->total_matrix,
|
|
||||||
&frame_bbox,ipage <= 1 ? 0 : ipage-1) )
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->page_asset_func &&
|
|
||||||
reader->page_asset_func(reader->page_asset_ctxt,
|
|
||||||
reader->device,
|
|
||||||
&reader->page_matrix,
|
|
||||||
&reader->total_matrix,
|
|
||||||
&reader->content_bbox,ipage <= 1 ? 0 : ipage-1) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return hpgs_showpage(reader->device,ipage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command PG (advance PaGe)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_PG(hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = hpgs_reader_showpage(reader,reader->current_page);
|
|
||||||
|
|
||||||
if (ret) return -1;
|
|
||||||
|
|
||||||
++reader->current_page;
|
|
||||||
|
|
||||||
// if wee are not in singlepage mode,
|
|
||||||
// try to set the individual page size.
|
|
||||||
if (reader->current_page > 0 &&
|
|
||||||
reader->plotsize_device &&
|
|
||||||
(hpgs_device_capabilities(reader->device) & HPGS_DEVICE_CAP_MULTISIZE))
|
|
||||||
{
|
|
||||||
hpgs_bbox page_bb;
|
|
||||||
int ret = hpgs_getplotsize(reader->plotsize_device,reader->current_page,&page_bb);
|
|
||||||
|
|
||||||
if (ret < 0) return -1;
|
|
||||||
|
|
||||||
// if ret is 1, we got the overall bounding box and the plotsize device
|
|
||||||
// knows about no more pages.
|
|
||||||
// So we stop the interpretation at this point.
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
// set the plotsize of the next page.
|
|
||||||
if (reader->verbosity)
|
|
||||||
hpgs_log(hpgs_i18n("Bounding Box of Page %d: %g %g %g %g.\n"),
|
|
||||||
reader->current_page,
|
|
||||||
page_bb.llx,page_bb.lly,
|
|
||||||
page_bb.urx,page_bb.ury );
|
|
||||||
|
|
||||||
// change the page layout.
|
|
||||||
hpgs_reader_set_page_matrix(reader,&page_bb);
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
|
|
||||||
if (hpgs_setplotsize(reader->device,&reader->page_bbox) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop the interpretation, if we are in singlepage mode.
|
|
||||||
return reader->current_page > 0 ? 0 : 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command UL (User defined Linetype)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_UL (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int itype,nsegs;
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
{
|
|
||||||
memcpy(reader->linetype_nsegs,std_linetype_nsegs,sizeof(std_linetype_nsegs));
|
|
||||||
memcpy(reader->linetype_segs,std_linetype_segs,sizeof(std_linetype_segs));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpgs_reader_read_int(reader,&itype)) return -1;
|
|
||||||
|
|
||||||
if (itype < -8 || itype > 8)
|
|
||||||
return hpgs_set_error(hpgs_i18n("Illegal linetype %d given."),itype);
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
{
|
|
||||||
memcpy(reader->linetype_segs[8+itype],
|
|
||||||
std_linetype_segs[8+itype],sizeof(std_linetype_segs[0]));
|
|
||||||
memcpy(reader->linetype_segs[8-itype],
|
|
||||||
std_linetype_segs[8-itype],sizeof(std_linetype_segs[0]));
|
|
||||||
|
|
||||||
reader->linetype_nsegs[8+itype] = std_linetype_nsegs[8+itype];
|
|
||||||
reader->linetype_nsegs[8+itype] = std_linetype_nsegs[8-itype];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsegs = 0;
|
|
||||||
|
|
||||||
while (!reader->eoc)
|
|
||||||
{
|
|
||||||
double gap;
|
|
||||||
if (hpgs_reader_read_double(reader,&gap)) return -1;
|
|
||||||
|
|
||||||
reader->linetype_segs[8+itype][nsegs] = gap;
|
|
||||||
reader->linetype_segs[8-itype][nsegs] = gap;
|
|
||||||
++nsegs;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->linetype_nsegs[8+itype] = nsegs;
|
|
||||||
reader->linetype_nsegs[8-itype] = nsegs;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command MC (Merge Control)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_MC (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int mode=0,rop=252;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&mode)) return -1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&rop)) return -1;
|
|
||||||
|
|
||||||
reader->rop3 = mode ? rop : 252;
|
|
||||||
|
|
||||||
return hpgs_setrop3(reader->device,reader->rop3,
|
|
||||||
reader->src_transparency,
|
|
||||||
reader->pattern_transparency );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command TR (Transparency Mode)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_TR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int n=1;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&n)) return -1;
|
|
||||||
|
|
||||||
reader->src_transparency = (n != 0);
|
|
||||||
|
|
||||||
return hpgs_setrop3(reader->device,reader->rop3,
|
|
||||||
reader->src_transparency,
|
|
||||||
reader->pattern_transparency );
|
|
||||||
}
|
|
||||||
@@ -1,773 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgstransform.c 362 2006-10-16 14:13:48Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of the HPGL reader. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include <hpgsreader.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
//#define HPGS_DEBUG_XFORM
|
|
||||||
|
|
||||||
static void apply_scale(hpgs_reader *reader,
|
|
||||||
const hpgs_point *p1, const hpgs_point *p2)
|
|
||||||
{
|
|
||||||
double xf,yf;
|
|
||||||
double dx = 0.0,dy=0.0;
|
|
||||||
hpgs_point p2u;
|
|
||||||
|
|
||||||
if (reader->sc_type < 0) return;
|
|
||||||
|
|
||||||
// get P2 in old user coordinates
|
|
||||||
p2u.x = reader->frame_x + p2->x * HP_TO_PT;
|
|
||||||
p2u.y = reader->frame_y + p2->y * HP_TO_PT;
|
|
||||||
|
|
||||||
hpgs_matrix_ixform(&p2u,&p2u,&reader->world_matrix);
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
{
|
|
||||||
hpgs_point p1u;
|
|
||||||
|
|
||||||
p1u.x = reader->frame_x + p1->x * HP_TO_PT;
|
|
||||||
p1u.y = reader->frame_y + p1->y * HP_TO_PT;
|
|
||||||
|
|
||||||
hpgs_matrix_ixform(&p1u,&reader->world_matrix,&p1u);
|
|
||||||
|
|
||||||
hpgs_log("SC: P1 = %g,%g.\n",p1->x,p1->y);
|
|
||||||
hpgs_log("SC: P2 = %g,%g.\n",p2->x,p2->y);
|
|
||||||
hpgs_log("SC: p1u = %g,%g.\n",p1u.x,p1u.y);
|
|
||||||
hpgs_log("SC: p2u = %g,%g.\n",p2u.x,p2u.y);
|
|
||||||
hpgs_log("SC: xmin,xmax = %g,%g.\n",reader->sc_xmin,reader->sc_xmax);
|
|
||||||
hpgs_log("SC: ymin,ymax = %g,%g.\n",reader->sc_ymin,reader->sc_ymax);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (reader->sc_type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
xf = p2u.x / (reader->sc_xmax - reader->sc_xmin);
|
|
||||||
yf = p2u.y / (reader->sc_ymax - reader->sc_ymin);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
xf = p2u.x / (reader->sc_xmax - reader->sc_xmin);
|
|
||||||
yf = p2u.y / (reader->sc_ymax - reader->sc_ymin);
|
|
||||||
|
|
||||||
if (xf < yf)
|
|
||||||
{
|
|
||||||
dy = (yf-xf) * (reader->sc_ymax - reader->sc_ymin) * 0.01 * reader->sc_left;
|
|
||||||
yf = xf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dx = (xf-yf) * (reader->sc_xmax - reader->sc_xmin) * 0.01 * reader->sc_bottom;
|
|
||||||
xf = yf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
xf = reader->sc_xmax;
|
|
||||||
yf = reader->sc_ymax;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("SC: xf,yf = %g,%g.\n",xf,yf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dx -= reader->sc_xmin * xf;
|
|
||||||
dy -= reader->sc_ymin * yf;
|
|
||||||
|
|
||||||
// concatenate transofrmation matrices.
|
|
||||||
//
|
|
||||||
// | 1 0 0 | | 1 0 0 |
|
|
||||||
// | x0 mxx mxy |* | dx xf 0 | =
|
|
||||||
// | y0 myx myy | | dy 0 yf |
|
|
||||||
//
|
|
||||||
// | 1 0 0 |
|
|
||||||
// | x0+mxx*dx+mxy*dy mxx*xf mxy*yf |
|
|
||||||
// | y0+myx*dx+myy*dy myx*xf myy*yf |
|
|
||||||
//
|
|
||||||
|
|
||||||
reader->world_matrix.dx += reader->world_matrix.mxx*dx + reader->world_matrix.mxy*dy;
|
|
||||||
reader->world_matrix.dy += reader->world_matrix.myx*dx + reader->world_matrix.myy*dy;
|
|
||||||
|
|
||||||
reader->world_matrix.mxx *= xf;
|
|
||||||
reader->world_matrix.myx *= xf;
|
|
||||||
reader->world_matrix.mxy *= yf;
|
|
||||||
reader->world_matrix.myy *= yf;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("SC: %10g %10g %10g\n",reader->world_matrix.dx,reader->world_matrix.mxx,reader->world_matrix.mxy);
|
|
||||||
hpgs_log("SC: %10g %10g %10g\n",reader->world_matrix.dy,reader->world_matrix.myx,reader->world_matrix.myy);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void hpgs_reader_set_default_transformation (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
// transformation matrix for user to PS coordinates.
|
|
||||||
int angle = reader->y_size >= reader->x_size ? 90 : 0;
|
|
||||||
|
|
||||||
hpgs_point p1 = reader->P1;
|
|
||||||
hpgs_point p2 = reader->P2;
|
|
||||||
|
|
||||||
angle += reader->rotation;
|
|
||||||
|
|
||||||
if ((angle % 180) == 90)
|
|
||||||
{
|
|
||||||
p2.y -= p1.y;
|
|
||||||
p1.y = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
reader->world_matrix.dx = reader->frame_x + p1.x * HP_TO_PT;
|
|
||||||
reader->world_matrix.dy = reader->frame_y + p1.y * HP_TO_PT;
|
|
||||||
|
|
||||||
switch (angle % 360)
|
|
||||||
{
|
|
||||||
case 90:
|
|
||||||
reader->world_matrix.mxx = 0.0;
|
|
||||||
reader->world_matrix.mxy = -HP_TO_PT;
|
|
||||||
reader->world_matrix.myx = HP_TO_PT;
|
|
||||||
reader->world_matrix.myy = 0.0;
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
reader->world_matrix.mxx = -HP_TO_PT;
|
|
||||||
reader->world_matrix.mxy = 0.0;
|
|
||||||
reader->world_matrix.myx = 0.0;
|
|
||||||
reader->world_matrix.myy = -HP_TO_PT;
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
reader->world_matrix.mxx = 0.0;
|
|
||||||
reader->world_matrix.mxy = HP_TO_PT;
|
|
||||||
reader->world_matrix.myx = -HP_TO_PT;
|
|
||||||
reader->world_matrix.myy = 0.0;
|
|
||||||
break;
|
|
||||||
default: // 0
|
|
||||||
reader->world_matrix.mxx = HP_TO_PT;
|
|
||||||
reader->world_matrix.mxy = 0.0;
|
|
||||||
reader->world_matrix.myx = 0.0;
|
|
||||||
reader->world_matrix.myy = HP_TO_PT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("xform: %10g %10g %10g\n",reader->world_matrix.dx,reader->world_matrix.mxx,reader->world_matrix.mxy);
|
|
||||||
hpgs_log("xform: %10g %10g %10g\n",reader->world_matrix.dy,reader->world_matrix.myx,reader->world_matrix.myy);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
apply_scale(reader,&p1,&p2);
|
|
||||||
|
|
||||||
reader->world_scale =
|
|
||||||
sqrt (fabs(reader->world_matrix.mxx * reader->world_matrix.myy -
|
|
||||||
reader->world_matrix.mxy * reader->world_matrix.myx ) );
|
|
||||||
|
|
||||||
// finally transform from model space to the page.
|
|
||||||
hpgs_matrix_concat(&reader->total_matrix,&reader->page_matrix,&reader->world_matrix);
|
|
||||||
|
|
||||||
reader->total_scale = reader->page_scale * reader->world_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command PS (Plot Size)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_PS (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double x_size=reader->x_size/HP_TO_PT;
|
|
||||||
double y_size=reader->y_size/HP_TO_PT;
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
{
|
|
||||||
// Well it seems, that some oldstyle HPGL files use
|
|
||||||
// PS w/o arguments in order to enforce a coordinate setup
|
|
||||||
// as if a portrait paper size has been selected.
|
|
||||||
// (resulting in a prerotation of 90 degrees).
|
|
||||||
x_size = 33600.0;
|
|
||||||
y_size = 47520.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&x_size)) return -1;
|
|
||||||
|
|
||||||
// set y-size to sqrt(0.5) * x_size in order to prevent
|
|
||||||
// the picture from rotation. This is better then setting
|
|
||||||
// the y-size to the (fictional) hard-clip limit, because
|
|
||||||
// without rotation we definitely can calculate our own plotsize
|
|
||||||
// using -i.
|
|
||||||
if (reader->eoc)
|
|
||||||
y_size = sqrt(0.5) * x_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_double(reader,&y_size)) return -1;
|
|
||||||
|
|
||||||
return hpgs_reader_set_plotsize (reader,x_size,y_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Actually set the plot size. User by PS command above and by PJL parser.
|
|
||||||
*/
|
|
||||||
int hpgs_reader_set_plotsize (hpgs_reader *reader, double x_size, double y_size)
|
|
||||||
{
|
|
||||||
hpgs_bbox bb = { 0.0,0.0,x_size*HP_TO_PT,y_size*HP_TO_PT };
|
|
||||||
|
|
||||||
reader->x_size = x_size;
|
|
||||||
reader->y_size = y_size;
|
|
||||||
|
|
||||||
if (y_size >= x_size)
|
|
||||||
{
|
|
||||||
reader->P1.x = x_size;
|
|
||||||
reader->P1.y = 0.0;
|
|
||||||
reader->P2.x = 0.0;
|
|
||||||
reader->P2.y = y_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader->P1.x = 0.0;
|
|
||||||
reader->P1.y = 0.0;
|
|
||||||
reader->P2.x = x_size;
|
|
||||||
reader->P2.y = y_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->delta_P.x = reader->P2.x - reader->P1.x;
|
|
||||||
reader->delta_P.y = reader->P2.y - reader->P1.y;
|
|
||||||
|
|
||||||
// undo any effects from an RO or SC statement.
|
|
||||||
reader->rotation = 0;
|
|
||||||
reader->sc_type = -1;
|
|
||||||
|
|
||||||
// change the page matrix only, if we don't have a plotsize device.
|
|
||||||
if (!reader->plotsize_device)
|
|
||||||
hpgs_reader_set_page_matrix (reader,&bb);
|
|
||||||
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
|
|
||||||
// report plot size only if
|
|
||||||
// when we don't have a plotsize device at hands.
|
|
||||||
if (reader->plotsize_device)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return hpgs_setplotsize(reader->device,&reader->page_bbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Change the page matrix according to this content bounding box.
|
|
||||||
*/
|
|
||||||
void hpgs_reader_set_page_matrix (hpgs_reader *reader, const hpgs_bbox *bb)
|
|
||||||
{
|
|
||||||
hpgs_bbox rbb;
|
|
||||||
double xscale,yscale;
|
|
||||||
hpgs_point rcp;
|
|
||||||
|
|
||||||
hpgs_matrix_ixform(&rcp,&reader->current_point,&reader->page_matrix);
|
|
||||||
|
|
||||||
// save the content bounding box for propagating it to the
|
|
||||||
// page_asset function.
|
|
||||||
reader->content_bbox = *bb;
|
|
||||||
|
|
||||||
if (reader->page_mode == 0)
|
|
||||||
{
|
|
||||||
reader->page_bbox = *bb;
|
|
||||||
hpgs_matrix_set_identity(&reader->page_matrix);
|
|
||||||
reader->page_scale = 1.0;
|
|
||||||
goto restore_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->page_matrix.mxx = cos(reader->page_angle * M_PI / 180.0);
|
|
||||||
reader->page_matrix.mxy = -sin(reader->page_angle * M_PI / 180.0);
|
|
||||||
|
|
||||||
reader->page_matrix.myx = sin(reader->page_angle * M_PI / 180.0);
|
|
||||||
reader->page_matrix.myy = cos(reader->page_angle * M_PI / 180.0);
|
|
||||||
|
|
||||||
reader->page_matrix.dx = 0.0;
|
|
||||||
reader->page_matrix.dy = 0.0;
|
|
||||||
|
|
||||||
if (reader->page_mode == 2) // dynamic page.
|
|
||||||
{
|
|
||||||
hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb);
|
|
||||||
|
|
||||||
reader->page_bbox.llx = 0.0;
|
|
||||||
reader->page_bbox.lly = 0.0;
|
|
||||||
|
|
||||||
reader->page_bbox.urx = (rbb.urx-rbb.llx) + 2.0 * reader->page_border;
|
|
||||||
reader->page_bbox.ury = (rbb.ury-rbb.lly) + 2.0 * reader->page_border;
|
|
||||||
|
|
||||||
reader->page_matrix.dx = reader->page_border - rbb.llx;
|
|
||||||
reader->page_matrix.dy = reader->page_border - rbb.lly;
|
|
||||||
|
|
||||||
// do we fit on the maximal page size?
|
|
||||||
if ((reader->page_width <= 0.0 || reader->page_bbox.urx <= reader->page_width) &&
|
|
||||||
(reader->page_height <= 0.0 || reader->page_bbox.ury <= reader->page_height) )
|
|
||||||
{
|
|
||||||
reader->page_scale = 1.0;
|
|
||||||
goto restore_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->page_bbox.urx > reader->page_width)
|
|
||||||
xscale = reader->page_width/reader->page_bbox.urx;
|
|
||||||
else
|
|
||||||
xscale = 1.0;
|
|
||||||
|
|
||||||
if (reader->page_bbox.ury> reader->page_height)
|
|
||||||
yscale = reader->page_height/reader->page_bbox.ury;
|
|
||||||
else
|
|
||||||
yscale = 1.0;
|
|
||||||
|
|
||||||
reader->page_scale = HPGS_MIN(xscale,yscale);
|
|
||||||
|
|
||||||
double rscale = 0.0;
|
|
||||||
double xx = 1.0;
|
|
||||||
|
|
||||||
// transform the scale to a human-interceptable scale.
|
|
||||||
do
|
|
||||||
{
|
|
||||||
xx *= 0.1;
|
|
||||||
rscale = floor(reader->page_scale / xx);
|
|
||||||
}
|
|
||||||
while (rscale < 2.0);
|
|
||||||
|
|
||||||
reader->page_scale = rscale * xx;
|
|
||||||
|
|
||||||
reader->page_matrix.mxx *= reader->page_scale;
|
|
||||||
reader->page_matrix.mxy *= reader->page_scale;
|
|
||||||
|
|
||||||
reader->page_matrix.myx *= reader->page_scale;
|
|
||||||
reader->page_matrix.myy *= reader->page_scale;
|
|
||||||
|
|
||||||
reader->page_matrix.dx *= reader->page_scale;
|
|
||||||
reader->page_matrix.dy *= reader->page_scale;
|
|
||||||
|
|
||||||
reader->page_bbox.urx *= reader->page_scale;
|
|
||||||
reader->page_bbox.ury *= reader->page_scale;
|
|
||||||
|
|
||||||
goto restore_cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fixed page.
|
|
||||||
reader->page_bbox.llx = 0.0;
|
|
||||||
reader->page_bbox.lly = 0.0;
|
|
||||||
|
|
||||||
reader->page_bbox.urx = reader->page_width;
|
|
||||||
reader->page_bbox.ury = reader->page_height;
|
|
||||||
|
|
||||||
hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb);
|
|
||||||
|
|
||||||
xscale = (reader->page_width - 2.0 * reader->page_border) / (rbb.urx-rbb.llx);
|
|
||||||
yscale = (reader->page_height - 2.0 * reader->page_border) / (rbb.ury-rbb.lly);
|
|
||||||
|
|
||||||
reader->page_scale = HPGS_MIN(xscale,yscale);
|
|
||||||
|
|
||||||
reader->page_matrix.mxx *= reader->page_scale;
|
|
||||||
reader->page_matrix.mxy *= reader->page_scale;
|
|
||||||
|
|
||||||
reader->page_matrix.myx *= reader->page_scale;
|
|
||||||
reader->page_matrix.myy *= reader->page_scale;
|
|
||||||
|
|
||||||
if (reader->page_scale == xscale)
|
|
||||||
{
|
|
||||||
reader->page_matrix.dx = reader->page_border - reader->page_scale * rbb.llx;
|
|
||||||
reader->page_matrix.dy =
|
|
||||||
0.5 * (reader->page_height - reader->page_scale * (rbb.ury-rbb.lly)) - reader->page_scale * rbb.lly;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader->page_matrix.dx =
|
|
||||||
0.5 * (reader->page_width - reader->page_scale * (rbb.urx-rbb.llx)) - reader->page_scale * rbb.llx;
|
|
||||||
reader->page_matrix.dy = reader->page_border - reader->page_scale * rbb.lly;
|
|
||||||
}
|
|
||||||
|
|
||||||
restore_cb:
|
|
||||||
hpgs_matrix_xform(&reader->current_point,&reader->page_matrix,&rcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command FR (advance FRame)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_FR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double advance = reader->x_size;
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&advance)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
while (reader->clipsave_depth > 0)
|
|
||||||
{
|
|
||||||
hpgs_cliprestore(reader->device);
|
|
||||||
--reader->clipsave_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->frame_asset_func)
|
|
||||||
{
|
|
||||||
hpgs_bbox frame_bbox;
|
|
||||||
|
|
||||||
frame_bbox.llx = reader->frame_x == 0.0 ? reader->content_bbox.llx : reader->frame_x;
|
|
||||||
frame_bbox.lly = reader->content_bbox.lly;
|
|
||||||
frame_bbox.urx = reader->frame_x + advance * HP_TO_PT;
|
|
||||||
frame_bbox.ury = reader->content_bbox.ury;
|
|
||||||
|
|
||||||
if (frame_bbox.urx > frame_bbox.llx)
|
|
||||||
{
|
|
||||||
int ipage = reader->current_page;
|
|
||||||
|
|
||||||
if (reader->frame_asset_func(reader->frame_asset_ctxt,
|
|
||||||
reader->device,
|
|
||||||
&reader->page_matrix,
|
|
||||||
&reader->total_matrix,
|
|
||||||
&frame_bbox,ipage <= 1 ? 0 : ipage-1) )
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->frame_x += advance * HP_TO_PT;
|
|
||||||
reader->P1.x -= advance;
|
|
||||||
reader->P2.x -= advance;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command RO (ROtate)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_RO (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
int rot=0;
|
|
||||||
hpgs_point p1,p2;
|
|
||||||
double dx,dy;
|
|
||||||
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&rot)) return -1;
|
|
||||||
|
|
||||||
switch ((rot - reader->rotation) % 360)
|
|
||||||
{
|
|
||||||
case 90:
|
|
||||||
p1.x = -reader->P1.y;
|
|
||||||
p1.y = reader->P1.x;
|
|
||||||
p2.x = -reader->P2.y;
|
|
||||||
p2.y = reader->P2.x;
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
p1.x = -reader->P1.x;
|
|
||||||
p1.y = -reader->P1.y;
|
|
||||||
p2.x = -reader->P2.x;
|
|
||||||
p2.y = -reader->P2.x;
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
p1.x = reader->P1.y;
|
|
||||||
p1.y = -reader->P1.x;
|
|
||||||
p2.x = reader->P2.y;
|
|
||||||
p2.y = -reader->P2.x;
|
|
||||||
break;
|
|
||||||
default: /* 0,360 */
|
|
||||||
p1.x = reader->P1.x;
|
|
||||||
p1.y = reader->P1.y;
|
|
||||||
p2.x = reader->P2.x;
|
|
||||||
p2.y = reader->P2.x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = p1.x < p2.x ? p1.x : p2.x;
|
|
||||||
dy = p1.y < p2.y ? p1.y : p2.y;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("RO: rot_old,rot = %d,%d.\n",reader->rotation,rot);
|
|
||||||
hpgs_log("RO: P1 = %g,%g.\n",reader->P1.x,reader->P1.y);
|
|
||||||
hpgs_log("RO: P2 = %g,%g.\n",reader->P2.x,reader->P2.y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reader->P1.x = p1.x-dx;
|
|
||||||
reader->P1.y = p1.y-dy;
|
|
||||||
reader->P2.x = p2.x-dx;
|
|
||||||
reader->P2.y = p2.y-dy;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("RO: P1 = %g,%g.\n",reader->P1.x,reader->P1.y);
|
|
||||||
hpgs_log("RO: P2 = %g,%g.\n",reader->P2.x,reader->P2.y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reader->rotation = rot;
|
|
||||||
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command SC (SCale)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_SC (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
double xmin,xmax,ymin,ymax,left=50.0,bottom=50.0;
|
|
||||||
int type=0;
|
|
||||||
|
|
||||||
if (reader->eoc)
|
|
||||||
{
|
|
||||||
reader->sc_type = -1;
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hpgs_reader_read_double(reader,&xmin)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&xmax)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&ymin)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&ymax)) return -1;
|
|
||||||
if (!reader->eoc &&
|
|
||||||
hpgs_reader_read_int(reader,&type)) return -1;
|
|
||||||
|
|
||||||
if (type == 1 && !reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&left)) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&bottom)) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->sc_type = type;
|
|
||||||
reader->sc_xmin = xmin;
|
|
||||||
reader->sc_xmax = xmax;
|
|
||||||
reader->sc_ymin = ymin;
|
|
||||||
reader->sc_ymax = ymax;
|
|
||||||
reader->sc_bottom = bottom;
|
|
||||||
reader->sc_left = left;
|
|
||||||
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command IP (Input Point)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_IP (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
// get default input point.
|
|
||||||
int angle = reader->y_size >= reader->x_size ? 90 : 0;
|
|
||||||
|
|
||||||
angle += reader->rotation;
|
|
||||||
|
|
||||||
switch (angle % 360)
|
|
||||||
{
|
|
||||||
case 90:
|
|
||||||
reader->P1.x = reader->x_size;
|
|
||||||
reader->P1.y = 0.0;
|
|
||||||
reader->P2.x = 0.0;
|
|
||||||
reader->P2.y = reader->y_size;
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
break;
|
|
||||||
reader->P1.x = reader->x_size;
|
|
||||||
reader->P1.y = reader->y_size;
|
|
||||||
reader->P2.x = 0.0;
|
|
||||||
reader->P2.y = 0.0;
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
reader->P1.x = 0.0;
|
|
||||||
reader->P1.y = reader->y_size;
|
|
||||||
reader->P2.x = reader->x_size;
|
|
||||||
reader->P2.y = 0.0;
|
|
||||||
break;
|
|
||||||
default: /* 0 */
|
|
||||||
reader->P1.x = 0.0;
|
|
||||||
reader->P1.y = 0.0;
|
|
||||||
reader->P2.x = reader->x_size;
|
|
||||||
reader->P2.y = reader->y_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// read input point
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,
|
|
||||||
angle%180 ?
|
|
||||||
&reader->P1.y :
|
|
||||||
&reader->P1.x )) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,angle%180 ?
|
|
||||||
&reader->P2.x :
|
|
||||||
&reader->P1.y )) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,
|
|
||||||
angle%180 ?
|
|
||||||
&reader->P2.y :
|
|
||||||
&reader->P2.x )) return -1;
|
|
||||||
if (reader->eoc) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,
|
|
||||||
angle%180 ?
|
|
||||||
&reader->P1.x :
|
|
||||||
&reader->P2.y )) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->delta_P.x = reader->P2.x - reader->P1.x;
|
|
||||||
reader->delta_P.y = reader->P2.y - reader->P1.y;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("IP: angle = %d.\n",angle);
|
|
||||||
hpgs_log("IP: P1 = %g,%g.\n",reader->P1.x,reader->P1.y);
|
|
||||||
hpgs_log("IP: P2 = %g,%g.\n",reader->P2.x,reader->P2.y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reader->sc_type = -1;
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command IR (Input point Relative)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_IR (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
// get default input point.
|
|
||||||
double p1x=0.0,p1y=0.0,p2x,p2y;
|
|
||||||
|
|
||||||
int angle = reader->y_size >= reader->x_size ? 90 : 0;
|
|
||||||
|
|
||||||
angle += reader->rotation;
|
|
||||||
|
|
||||||
switch (angle % 360)
|
|
||||||
{
|
|
||||||
case 90:
|
|
||||||
p1x = reader->x_size;
|
|
||||||
p1y = 0.0;
|
|
||||||
p2x = 0.0;
|
|
||||||
p2y = reader->y_size;
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
break;
|
|
||||||
p1x = reader->x_size;
|
|
||||||
p1y = reader->y_size;
|
|
||||||
p2x = 0.0;
|
|
||||||
p2y = 0.0;
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
p1x = 0.0;
|
|
||||||
p1y = reader->y_size;
|
|
||||||
p2x = reader->x_size;
|
|
||||||
p2y = 0.0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
p1x = 0.0;
|
|
||||||
p1y = 0.0;
|
|
||||||
p2x = reader->x_size;
|
|
||||||
p2y = reader->y_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read input point
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
double x,y;
|
|
||||||
|
|
||||||
if (hpgs_reader_read_double(reader,&x)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&y)) return -1;
|
|
||||||
|
|
||||||
p1x = reader->x_size * x * 0.01;
|
|
||||||
p2x = p1x + reader->delta_P.x;
|
|
||||||
p1y = reader->y_size * y * 0.01;
|
|
||||||
p2y = p1y + reader->delta_P.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reader->eoc)
|
|
||||||
{
|
|
||||||
if (hpgs_reader_read_double(reader,&p2x)) return -1;
|
|
||||||
if (hpgs_reader_read_double(reader,&p2y)) return -1;
|
|
||||||
|
|
||||||
p2x = reader->x_size * p2x * 0.01;
|
|
||||||
p2y = reader->y_size * p2y * 0.01;
|
|
||||||
|
|
||||||
reader->delta_P.x = p2x - p1x;
|
|
||||||
reader->delta_P.y = p2y - p1y;
|
|
||||||
}
|
|
||||||
|
|
||||||
reader->P1.x = p1x;
|
|
||||||
reader->P1.y = p1y;
|
|
||||||
reader->P2.x = p2x;
|
|
||||||
reader->P2.y = p2y;
|
|
||||||
|
|
||||||
#ifdef HPGS_DEBUG_XFORM
|
|
||||||
hpgs_log("IR: P1 = %g,%g.\n",reader->P1.x,reader->P1.y);
|
|
||||||
hpgs_log("IR: P2 = %g,%g.\n",reader->P2.x,reader->P2.y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hpgs_reader_set_default_transformation(reader);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
HPGL command IW (Input Window)
|
|
||||||
*/
|
|
||||||
int hpgs_reader_do_IW (hpgs_reader *reader)
|
|
||||||
{
|
|
||||||
// get default input point.
|
|
||||||
hpgs_point ll;
|
|
||||||
hpgs_point ur;
|
|
||||||
hpgs_point p;
|
|
||||||
|
|
||||||
if (hpgs_reader_checkpath(reader)) return -1;
|
|
||||||
|
|
||||||
while (reader->clipsave_depth > 0)
|
|
||||||
{
|
|
||||||
hpgs_cliprestore(reader->device);
|
|
||||||
--reader->clipsave_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader->eoc) return 0;
|
|
||||||
|
|
||||||
// read input point
|
|
||||||
if (hpgs_reader_read_point(reader,&ll,1)) return -1;
|
|
||||||
if (hpgs_reader_read_point(reader,&ur,1)) return -1;
|
|
||||||
|
|
||||||
if (hpgs_clipsave(reader->device)) return -1;
|
|
||||||
++reader->clipsave_depth;
|
|
||||||
|
|
||||||
if (hpgs_newpath(reader->device)) return -1;
|
|
||||||
if (hpgs_moveto(reader->device,&ll)) return -1;
|
|
||||||
p.x = ll.x;
|
|
||||||
p.y = ur.y;
|
|
||||||
if (hpgs_lineto(reader->device,&p)) return -1;
|
|
||||||
if (hpgs_lineto(reader->device,&ur)) return -1;
|
|
||||||
p.x = ur.x;
|
|
||||||
p.y = ll.y;
|
|
||||||
if (hpgs_lineto(reader->device,&p)) return -1;
|
|
||||||
if (hpgs_closepath(reader->device)) return -1;
|
|
||||||
if (hpgs_clip(reader->device,HPGS_TRUE)) return -1;
|
|
||||||
|
|
||||||
reader->have_current_point = 0;
|
|
||||||
|
|
||||||
return hpgs_newpath(reader->device);
|
|
||||||
}
|
|
||||||
@@ -1,329 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* $Id: hpgszostream.c 368 2006-12-31 15:18:08Z softadm $
|
|
||||||
* *
|
|
||||||
* hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript *
|
|
||||||
* API for rendering a scene and thus renders to a variety of *
|
|
||||||
* devices and fileformats. *
|
|
||||||
* *
|
|
||||||
* (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at *
|
|
||||||
* *
|
|
||||||
* Author: Wolfgang Glas *
|
|
||||||
* *
|
|
||||||
* hpgs is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Lesser General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2.1 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* hpgs 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 *
|
|
||||||
* Lesser General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Lesser General Public *
|
|
||||||
* License along with this library; if not, write to the *
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
|
|
||||||
* Boston, MA 02111-1307 USA *
|
|
||||||
* *
|
|
||||||
***********************************************************************
|
|
||||||
* *
|
|
||||||
* The implementation of a deflate output stream. *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include<hpgs.h>
|
|
||||||
#include<string.h>
|
|
||||||
#include<zlib.h>
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <malloc.h>
|
|
||||||
#else
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Internals of hpgs_z_ostream
|
|
||||||
typedef struct hpgs_z_ostream_stream_st hpgs_z_ostream_stream;
|
|
||||||
|
|
||||||
#define Z_OSTREAM_BUF_SIZE 16384
|
|
||||||
#define Z_OSTREAM_XFER_SIZE 4096
|
|
||||||
|
|
||||||
struct hpgs_z_ostream_stream_st
|
|
||||||
{
|
|
||||||
hpgs_ostream *base;
|
|
||||||
|
|
||||||
int compression;
|
|
||||||
hpgs_bool take_base;
|
|
||||||
|
|
||||||
unsigned char buffer [Z_OSTREAM_BUF_SIZE];
|
|
||||||
unsigned char xfer [Z_OSTREAM_XFER_SIZE];
|
|
||||||
|
|
||||||
unsigned char *pptr;
|
|
||||||
|
|
||||||
int errflg;
|
|
||||||
|
|
||||||
z_stream zstream;
|
|
||||||
size_t total_bytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int z_init(hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (deflateInit(&stream->zstream,stream->compression)==Z_OK)
|
|
||||||
{
|
|
||||||
stream->zstream.next_out = (Bytef *)stream->xfer;
|
|
||||||
stream->zstream.avail_out = sizeof(stream->xfer);
|
|
||||||
stream->zstream.total_out = 0;
|
|
||||||
stream->zstream.avail_in = 0;
|
|
||||||
stream->zstream.total_in = 0;
|
|
||||||
stream->total_bytes = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_consume(hpgs_z_ostream_stream *stream, int flags)
|
|
||||||
{
|
|
||||||
int cnt=stream->pptr-stream->buffer;
|
|
||||||
|
|
||||||
int zret;
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if (!stream->zstream.next_out && z_init(stream)) return EOF;
|
|
||||||
|
|
||||||
if (cnt <= 0 && flags == Z_NO_FLUSH) return 0;
|
|
||||||
|
|
||||||
stream->zstream.avail_in=cnt;
|
|
||||||
stream->zstream.total_in=0;
|
|
||||||
stream->zstream.next_in=(Bytef *)stream->buffer;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
stream->zstream.avail_out=Z_OSTREAM_XFER_SIZE;
|
|
||||||
stream->zstream.total_out=0;
|
|
||||||
stream->zstream.next_out=(Bytef *)stream->xfer;
|
|
||||||
|
|
||||||
zret=deflate (&stream->zstream,flags);
|
|
||||||
|
|
||||||
if (hpgs_ostream_write(stream->xfer,1,stream->zstream.total_out,stream->base) < stream->zstream.total_out)
|
|
||||||
{ stream->errflg = 1; return -1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
while (zret == Z_OK &&
|
|
||||||
stream->zstream.avail_out == 0);
|
|
||||||
|
|
||||||
stream->pptr = stream->buffer;
|
|
||||||
|
|
||||||
|
|
||||||
if (stream->zstream.avail_in==0)
|
|
||||||
{
|
|
||||||
stream->total_bytes += cnt;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream->errflg = 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_putc (int c, hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->pptr >= stream->buffer + Z_OSTREAM_BUF_SIZE)
|
|
||||||
z_consume(stream,Z_NO_FLUSH);
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
*stream->pptr = c;
|
|
||||||
++stream->pptr;
|
|
||||||
|
|
||||||
return c & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_write (void *ptr, size_t size, size_t nmemb, hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
size_t tot_bytes = size*nmemb;
|
|
||||||
size_t avail_bytes = stream->buffer + Z_OSTREAM_BUF_SIZE - stream->pptr;
|
|
||||||
size_t put_bytes = tot_bytes < avail_bytes ? tot_bytes : avail_bytes;
|
|
||||||
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
memcpy(stream->pptr,ptr,put_bytes);
|
|
||||||
stream->pptr += put_bytes;
|
|
||||||
|
|
||||||
while (stream->pptr >= stream->buffer + Z_OSTREAM_BUF_SIZE &&
|
|
||||||
z_consume(stream,Z_NO_FLUSH) == 0)
|
|
||||||
{
|
|
||||||
ptr += put_bytes;
|
|
||||||
tot_bytes -= put_bytes;
|
|
||||||
|
|
||||||
put_bytes = tot_bytes < Z_OSTREAM_BUF_SIZE ? tot_bytes : Z_OSTREAM_BUF_SIZE ;
|
|
||||||
|
|
||||||
memcpy(stream->pptr,ptr,put_bytes);
|
|
||||||
stream->pptr += put_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream->errflg ? 0 : nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_vprintf (hpgs_z_ostream_stream *stream, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
size_t size=1024;
|
|
||||||
char *buf;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (stream->errflg)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
buf = hpgs_alloca(size);
|
|
||||||
|
|
||||||
/* Try to print in the allocated space. */
|
|
||||||
va_list aq;
|
|
||||||
va_copy(aq, ap);
|
|
||||||
#ifdef WIN32
|
|
||||||
n = _vsnprintf (buf, size, fmt, aq);
|
|
||||||
#else
|
|
||||||
n = vsnprintf (buf, size, fmt, aq);
|
|
||||||
#endif
|
|
||||||
va_end(aq);
|
|
||||||
|
|
||||||
/* If that worked, push the string. */
|
|
||||||
if (n > -1 && n < size)
|
|
||||||
return z_write(buf,n,1,stream) ? n : -1;
|
|
||||||
|
|
||||||
/* Else try again with more space. */
|
|
||||||
if (n < 0)
|
|
||||||
size *= 2;
|
|
||||||
else
|
|
||||||
size = n+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_flush (hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->zstream.next_out == 0 && stream->pptr <= stream->buffer) return 0;
|
|
||||||
int ret = z_consume(stream,Z_FINISH);
|
|
||||||
|
|
||||||
deflateEnd (&stream->zstream);
|
|
||||||
stream->zstream.next_out = 0;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_close (hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
int ret=0;
|
|
||||||
|
|
||||||
if (stream->zstream.next_out)
|
|
||||||
deflateEnd (&stream->zstream);
|
|
||||||
|
|
||||||
if (stream->take_base && hpgs_ostream_close(stream->base))
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
free(stream);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_iserror (hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->errflg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_istream *z_getbuf (hpgs_z_ostream_stream *stream)
|
|
||||||
{
|
|
||||||
z_flush(stream);
|
|
||||||
return hpgs_ostream_getbuf(stream->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_tell (hpgs_z_ostream_stream *stream, int layer, size_t *pos)
|
|
||||||
{
|
|
||||||
if (layer > 0)
|
|
||||||
return hpgs_ostream_tell(stream->base,layer-1,pos);
|
|
||||||
else if (layer == 0)
|
|
||||||
{
|
|
||||||
*pos = stream->total_bytes;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int z_seek (hpgs_z_ostream_stream *stream, size_t pos)
|
|
||||||
{
|
|
||||||
// only seek(0) is supported in order to reuse the stream.
|
|
||||||
if (pos) return -1;
|
|
||||||
|
|
||||||
z_flush(stream);
|
|
||||||
|
|
||||||
return hpgs_ostream_seek(stream->base,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static hpgs_ostream_vtable z_vtable =
|
|
||||||
{
|
|
||||||
(hpgs_ostream_putc_func_t) z_putc,
|
|
||||||
(hpgs_ostream_write_func_t) z_write,
|
|
||||||
(hpgs_ostream_vprintf_func_t) z_vprintf,
|
|
||||||
(hpgs_ostream_flush_func_t) z_flush,
|
|
||||||
(hpgs_ostream_close_func_t) z_close,
|
|
||||||
(hpgs_ostream_iserror_func_t) z_iserror,
|
|
||||||
(hpgs_ostream_getbuf_func_t) z_getbuf,
|
|
||||||
(hpgs_ostream_tell_func_t) z_tell,
|
|
||||||
(hpgs_ostream_seek_func_t) z_seek,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Returns a new \c hpgs_ostream created on the heap,
|
|
||||||
which operates on a given \c hpgs_ostream and writes
|
|
||||||
the given data through a zlib deflate stream using
|
|
||||||
the given compression.
|
|
||||||
|
|
||||||
If \c take_base is false, the stream \c base is closed, when
|
|
||||||
the returned stream is closed. In this case, don't close it at
|
|
||||||
your own.
|
|
||||||
|
|
||||||
Returns a null pointer, when the system is out of memory.
|
|
||||||
*/
|
|
||||||
hpgs_ostream *hpgs_new_z_ostream (hpgs_ostream *base, int compression, hpgs_bool take_base)
|
|
||||||
{
|
|
||||||
hpgs_z_ostream_stream *stream;
|
|
||||||
hpgs_ostream *ret = (hpgs_ostream *)malloc(sizeof(hpgs_ostream));
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
stream =
|
|
||||||
(hpgs_z_ostream_stream *)malloc(sizeof(hpgs_z_ostream_stream));
|
|
||||||
|
|
||||||
if (!stream)
|
|
||||||
{
|
|
||||||
free (ret);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->base = base;
|
|
||||||
stream->compression = compression;
|
|
||||||
stream->take_base = take_base;
|
|
||||||
|
|
||||||
stream->zstream.zalloc = Z_NULL;
|
|
||||||
stream->zstream.zfree = Z_NULL;
|
|
||||||
stream->zstream.opaque = Z_NULL;
|
|
||||||
|
|
||||||
stream->zstream.next_out = 0;
|
|
||||||
stream->zstream.avail_out = 0;
|
|
||||||
stream->zstream.total_out = 0;
|
|
||||||
stream->zstream.avail_in = 0;
|
|
||||||
stream->zstream.total_in = 0;
|
|
||||||
stream->pptr = stream->buffer;
|
|
||||||
stream->total_bytes = 0;
|
|
||||||
stream->errflg = 0;
|
|
||||||
|
|
||||||
ret->stream = stream;
|
|
||||||
ret->vtable = &z_vtable;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user