- Delete "winecalc", there is no reason to keep it as we have our own calculator app now.

- Delete "smartpdf", it never worked and is outdated.

svn path=/trunk/; revision=33388
This commit is contained in:
Colin Finck 2008-05-09 11:58:30 +00:00
parent 9e45b56ced
commit 7b6887ffc8
585 changed files with 0 additions and 234120 deletions

View file

@ -83,14 +83,6 @@
<xi:include href="screenshot/screenshot.rbuild" />
</directory>
<!--
<directory name="smartpdf">
<xi:include href="smartpdf/fitz.rbuild" />
<xi:include href="smartpdf/poppler.rbuild" />
<xi:include href="smartpdf/smartpdf.rbuild" />
</directory>
-->
<directory name="sysutils">
<xi:include href="sysutils/sysutils.rbuild" />
</directory>
@ -99,10 +91,6 @@
<xi:include href="templates/directory.rbuild" />
</directory>
<directory name="winecalc">
<xi:include href="winecalc/winecalc.rbuild" />
</directory>
<directory name="winefile">
<xi:include href="winefile/winefile.rbuild" />
</directory>

View file

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,112 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "WinUtil.hpp"
#include "str_util.h"
// TODO: exe name might be unicode so to support everything cmd or args
// should be unicode or we can assume that cmd and args are utf8 and
// convert them to utf16 and call CreateProcessW
#define DONT_INHERIT_HANDLES FALSE
// Given name of the command to exececute 'cmd', and its arguments 'args'
// return WinProcess object that makes it easier to handle the process
// Returns NULL if failed to create the process. Caller can use GetLastError()
// for detailed error information.
WinProcess * WinProcess::Create(const char* cmd, char* args)
{
UINT res;
HANDLE stdOut = INVALID_HANDLE_VALUE;
HANDLE stdErr = INVALID_HANDLE_VALUE;
STARTUPINFOA siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = 1;
memzero(&siStartupInfo, sizeof(siStartupInfo));
memzero(&piProcessInfo, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
char stdoutTempName[MAX_PATH] = {0};
char stderrTempName[MAX_PATH] = {0};
char *stdoutTempNameCopy = NULL;
char *stderrTempNameCopy = NULL;
char buf[MAX_PATH] = {0};
int len = GetTempPathA(sizeof(buf), buf);
assert(len < sizeof(buf));
// create temporary files for capturing stdout and stderr or the command
res = GetTempFileNameA(buf, "stdout", 0, stdoutTempName);
if (0 == res)
goto Error;
res = GetTempFileNameA(buf, "stderr", 0, stderrTempName);
if (0 == res)
goto Error;
stdoutTempNameCopy = str_dup(stdoutTempName);
stderrTempNameCopy = str_dup(stderrTempName);
stdOut = CreateFileA(stdoutTempNameCopy,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ,
&sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
if (INVALID_HANDLE_VALUE == stdOut)
goto Error;
stdErr = CreateFileA(stderrTempNameCopy,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ,
&sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
if (INVALID_HANDLE_VALUE == stdErr)
goto Error;
siStartupInfo.hStdOutput = stdOut;
siStartupInfo.hStdError = stdErr;
BOOL ok = CreateProcessA(cmd, args, NULL, NULL, DONT_INHERIT_HANDLES,
CREATE_DEFAULT_ERROR_MODE, NULL /*env*/, NULL /*curr dir*/,
&siStartupInfo, &piProcessInfo);
if (!ok)
goto Error;
// TODO: pass stdoutTempNameCopy and stderrTempNameCopy so upon
// WinProcess destruction the files can be deleted and their memory freed
WinProcess *wp = new WinProcess(&piProcessInfo);
return wp;
Error:
if (INVALID_HANDLE_VALUE != stdOut) {
CloseHandle(stdOut);
}
if (INVALID_HANDLE_VALUE != stdErr) {
CloseHandle(stdErr);
}
if (stdoutTempName[0]) {
// TODO: delete stdoutTempName
}
if (stderrTempName[0]) {
// TODO: delete stderrTempName
}
free(stdoutTempNameCopy);
free(stderrTempNameCopy);
return NULL;
}
WinProcess::WinProcess(PROCESS_INFORMATION *pi)
{
memcpy(&m_processInfo, pi, sizeof(PROCESS_INFORMATION));
}

View file

@ -1,15 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef WINUTIL_HPP__
#define WINUTIL_HPP__
class WinProcess {
public:
static WinProcess* Create(const char *cmd, char *args="");
private:
WinProcess(PROCESS_INFORMATION *); // we don't want just anyone to make us
PROCESS_INFORMATION m_processInfo;
};
#endif

View file

@ -1,138 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
void swap_int(int *one, int *two)
{
int tmp = *one;
*one = *two;
*two = tmp;
}
void swap_double(double *one, double *two)
{
double tmp = *one;
*one = *two;
*two = tmp;
}
int MinInt(int one, int two)
{
if (one < two)
return one;
else
return two;
}
void memzero(void *data, size_t len)
{
memset(data, 0, len);
}
void *zmalloc(size_t len)
{
void *data = malloc(len);
if (data)
memzero(data, len);
return data;
}
/* TODO: probably should move to some other file and change name to
sleep_milliseconds */
void sleep_milliseconds(int milliseconds)
{
#ifdef WIN32
Sleep((DWORD)milliseconds);
#else
struct timespec tv;
int secs, nanosecs;
secs = milliseconds / 1000;
nanosecs = (milliseconds - (secs * 1000)) * 1000;
tv.tv_sec = (time_t) secs;
tv.tv_nsec = (long) nanosecs;
while (1)
{
int rval = nanosleep(&tv, &tv);
if (rval == 0)
/* Completed the entire sleep time; all done. */
return;
else if (errno == EINTR)
/* Interrupted by a signal. Try again. */
continue;
else
/* Some other error; bail out. */
return;
}
return;
#endif
}
/* milli-second timer */
#ifdef _WIN32
void ms_timer_start(ms_timer *timer)
{
assert(timer);
if (!timer)
return;
QueryPerformanceCounter(&timer->start);
}
void ms_timer_stop(ms_timer *timer)
{
assert(timer);
if (!timer)
return;
QueryPerformanceCounter(&timer->end);
}
double ms_timer_time_in_ms(ms_timer *timer)
{
LARGE_INTEGER freq;
double time_in_secs;
QueryPerformanceFrequency(&freq);
time_in_secs = (double)(timer->end.QuadPart-timer->start.QuadPart)/(double)freq.QuadPart;
return time_in_secs * 1000.0;
}
#else
typedef struct ms_timer {
struct timeval start;
struct timeval end;
} ms_timer;
void ms_timer_start(ms_timer *timer)
{
assert(timer);
if (!timer)
return;
gettimeofday(&timer->start, NULL);
}
void ms_timer_stop(ms_timer *timer)
{
assert(timer);
if (!timer)
return;
gettimeofday(&timer->end, NULL);
}
double ms_timer_time_in_ms(ms_timer *timer)
{
double timeInMs;
time_t seconds;
int usecs;
assert(timer);
if (!timer)
return 0.0;
/* TODO: this logic needs to be verified */
seconds = timer->end.tv_sec - timer->start.tv_sec;
usecs = timer->end.tv_usec - timer->start.tv_usec;
if (usecs < 0) {
--seconds;
usecs += 1000000;
}
timeInMs = (double)seconds*(double)1000.0 + (double)usecs/(double)1000.0;
return timeInMs;
}
#endif

View file

@ -1,160 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef BASE_UTIL_H_
#define BASE_UTIL_H_
#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
/* It seems that Visual C defines WIN32 for Windows code but _WINDOWS for WINCE projects,
so I'll make sure to set WIN32 always*/
#ifdef _WINDOWS
#ifndef WIN32
#define WIN32 1
#endif
#ifndef _WIN32
#define _WIN32 1
#endif
#endif
#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#else
#include <sys/time.h> // for timeval
#endif
/* Few most common includes for C stdlib */
#include <assert.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
// TODO: does it need to be __GNUC__ only? I think it was done for mingw
#ifdef __GNUC__
#include <stdarg.h>
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifdef _WIN32
#ifndef __GNUC__
typedef unsigned int uint32_t;
#endif
#ifndef _T
#define _T TEXT
#endif
#else
#define _T(x) x
/* TODO: if _UNICODE, it should be different */
#define TEXT(x) x
#endif
/* compile-time assert */
#ifndef CASSERT
#define CASSERT( exp, name ) typedef int dummy##name [ (exp ) ? 1 : -1 ];
#endif
/* Ugly name but the whole point is to make things shorter. */
#define SA(struct_name) (struct_name *)malloc(sizeof(struct_name))
#define SAZ(struct_name) (struct_name *)zmalloc(sizeof(struct_name))
typedef long long int64;
CASSERT( sizeof(int64)==8, int64_is_8_bytes )
#define dimof(X) (sizeof(X)/sizeof((X)[0]))
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct ms_timer {
#ifdef _WIN32
LARGE_INTEGER start;
LARGE_INTEGER end;
#else
struct timeval start;
struct timeval end;
#endif
} ms_timer;
#ifdef _WIN32
void win32_dbg_out(const char *format, ...);
void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen);
#endif
/* TODO: consider using standard C macros for SWAP and MIN */
void swap_int(int *one, int *two);
void swap_double(double *one, double *two);
int MinInt(int one, int two);
void memzero(void *data, size_t len);
void * zmalloc(size_t size);
void sleep_milliseconds(int milliseconds);
void ms_timer_start(ms_timer *timer);
void ms_timer_stop(ms_timer *timer);
double ms_timer_time_in_ms(ms_timer *timer);
#define LIST_REVERSE_FUNC_PROTO(func_name, TYPE) \
void func_name(TYPE **root)
#define LIST_REVERSE_FUNC(func_name, TYPE) \
void func_name(TYPE **root) \
{ \
TYPE * cur; \
TYPE * next; \
TYPE * new_first = NULL; \
\
if (!root) \
return; \
\
cur = *root; \
while (cur) { \
next = cur->next; \
cur->next = new_first; \
new_first = cur; \
cur = next; \
} \
*root = new_first; \
}
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
class MsTimer {
public:
MsTimer() { ms_timer_start(&timer); }
void start(void) { ms_timer_start(&timer); }
void stop(void) { ms_timer_stop(&timer); }
double timeInMs(void) { return ms_timer_time_in_ms(&timer); }
private:
ms_timer timer;
};
#endif
#endif

View file

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_unit_tests", "common_unit_tests.vcproj", "{35EC4096-521D-44D0-B693-2BF11B85B275}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.ActiveCfg = Debug|Win32
{35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.Build.0 = Debug|Win32
{35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.ActiveCfg = Release|Win32
{35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -1,246 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="common_unit_tests"
ProjectGUID="{35EC4096-521D-44D0-B693-2BF11B85B275}"
RootNamespace="common_unit_tests"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG;_WIN32"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\base_util.h"
>
</File>
<File
RelativePath=".\file_util.h"
>
</File>
<File
RelativePath=".\netstr.h"
>
</File>
<File
RelativePath=".\prefs.h"
>
</File>
<File
RelativePath=".\str_util.h"
>
</File>
<File
RelativePath=".\win_util.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\base_util.c"
>
</File>
<File
RelativePath=".\file_util.c"
>
</File>
<File
RelativePath=".\netstr.c"
>
</File>
<File
RelativePath=".\prefs.c"
>
</File>
<File
RelativePath=".\str_util.c"
>
</File>
<File
RelativePath=".\str_util_test.c"
>
</File>
<File
RelativePath=".\unit_tests_all.c"
>
</File>
<File
RelativePath=".\win_util.c"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -1,319 +0,0 @@
/****************************************************************************
*
* Dynamic strings
****************************************************************************/
/*
* tcl.h --
*
* This header file describes the externally-visible facilities
* of the Tcl interpreter.
*
* Copyright (c) 1987-1994 The Regents of the University of California.
* Copyright (c) 1994-1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39
*/
#include "dstring.h"
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "str_strsafe.h"
/*
*----------------------------------------------------------------------
*
* DStringInit --
*
* Initializes a dynamic string, discarding any previous contents
* of the string (DStringFree should have been called already
* if the dynamic string was previously in use).
*
* Results:
* None.
*
* Side effects:
* The dynamic string is initialized to be empty.
*
*----------------------------------------------------------------------
*/
void
DStringInit(DString* pDs)
{
pDs->pString = pDs->staticSpace;
pDs->length = 0;
pDs->spaceAvl = kDstringStaticSize;
pDs->staticSpace[0] = 0;
}
/*
*----------------------------------------------------------------------
*
* DStringAppend --
*
* Append more characters to the current value of a dynamic string.
*
* Results:
* The return value is a pointer to the dynamic string's new value.
*
* Side effects:
* Length bytes from string (or all of string if length is less
* than zero) are added to the current value of the string. Memory
* gets reallocated if needed to accomodate the string's new size.
*
*----------------------------------------------------------------------
*/
char *
DStringAppend(DString *pDs,
const char* string,
int length)
{
int newSize;
char* newString;
char* dst;
const char* end;
if (length < 0) {
length = strlen(string);
}
newSize = length + pDs->length;
/*
* Allocate a larger buffer for the string if the current one isn't
* large enough. Allocate extra space in the new buffer so that there
* will be room to grow before we have to allocate again.
*/
if (newSize >= pDs->spaceAvl) {
pDs->spaceAvl = newSize*2;
newString = (char *) malloc((unsigned) pDs->spaceAvl);
memcpy((void *)newString, (void *) pDs->pString,
(size_t) pDs->length);
if (pDs->pString != pDs->staticSpace) {
free(pDs->pString);
}
pDs->pString = newString;
}
/*
* Copy the new string into the buffer at the end of the old
* one.
*/
for (dst = pDs->pString + pDs->length, end = string+length;
string < end; string++, dst++) {
*dst = *string;
}
*dst = 0;
pDs->length += length;
return pDs->pString;
}
/*
*----------------------------------------------------------------------
*
* DStringSetLength --
*
* Change the length of a dynamic string. This can cause the
* string to either grow or shrink, depending on the value of
* length.
*
* Results:
* None.
*
* Side effects:
* The length of pDsis changed to length and a null byte is
* stored at that position in the string. If length is larger
* than the space allocated for pDs, then a panic occurs.
*
*----------------------------------------------------------------------
*/
void
DStringSetLength(DString* pDs,
int length)
{
if (length < 0) {
length = 0;
}
if (length >= pDs->spaceAvl) {
char *newString;
pDs->spaceAvl = length+1;
newString = (char *) malloc((unsigned) pDs->spaceAvl);
/*
* SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
* to a larger buffer, since there may be embedded NULLs in the
* string in some cases.
*/
memcpy((void *) newString, (void*) pDs->pString,
(size_t) pDs->length);
if (pDs->pString != pDs->staticSpace) {
free(pDs->pString);
}
pDs->pString = newString;
}
pDs->length = length;
pDs->pString[length] = 0;
}
/*
*----------------------------------------------------------------------
*
* DStringFree --
*
* Frees up any memory allocated for the dynamic string and
* reinitializes the string to an empty state.
*
* Results:
* None.
*
* Side effects:
* The previous contents of the dynamic string are lost, and
* the new value is an empty string.
*
*----------------------------------------------------------------------
*/
void
DStringFree(DString* pDs)
{
if (pDs->pString != pDs->staticSpace) {
free(pDs->pString);
}
pDs->pString = pDs->staticSpace;
pDs->length = 0;
pDs->spaceAvl = kDstringStaticSize;
pDs->staticSpace[0] = 0;
}
/*
* DStringSprintf --
*
* Append a formatted string to a dstring
*/
void
DStringSprintf(DString* pDs,
const char* pFormat,
...)
{
#ifdef _WIN32
HRESULT hr;
va_list args;
char message[256];
char * buf;
size_t bufCchSize;
char * result = NULL;
buf = &(message[0]);
bufCchSize = sizeof(message);
va_start(args, pFormat);
for (;;)
{
/* TODO: this only works on windows with recent C library */
hr = StringCchVPrintfA(buf, bufCchSize, pFormat, args);
if (S_OK == hr)
break;
if (STRSAFE_E_INSUFFICIENT_BUFFER != hr)
{
/* any error other than buffer not big enough:
a) should not happen
b) means we give up */
goto Error;
}
/* we have to make the buffer bigger. The algorithm used to calculate
the new size is arbitrary (aka. educated guess) */
if (buf != &(message[0]))
free(buf);
if (bufCchSize < 4*1024)
bufCchSize += bufCchSize;
else
bufCchSize += 1024;
buf = (char *)malloc(bufCchSize*sizeof(char));
if (NULL == buf)
goto Error;
}
va_end(args);
DStringAppend(pDs, buf, -1);
Error:
if (buf != &(message[0]))
free((void*)buf);
return;
#else
va_list args;
char* pBuffer;
int len;
va_start(args, pFormat);
len = vasprintf(&pBuffer, pFormat, args);
DStringAppend(pDs, pBuffer, len);
free(pBuffer);
va_end(args);
#endif
}
/****************************************************************************
* DStringAppendLowerCase --
*
* Append text to a dstring lowercased
*/
char*
DStringAppendLowerCase(DString* pDs,
const char* string,
int length)
{
int newSize;
char* newString;
char* dst;
const char* end;
if (length < 0) {
length = strlen(string);
}
newSize = length + pDs->length;
/*
* Allocate a larger buffer for the string if the current one isn't
* large enough. Allocate extra space in the new buffer so that there
* will be room to grow before we have to allocate again.
*/
if (newSize >= pDs->spaceAvl) {
pDs->spaceAvl = newSize*2;
newString = (char *) malloc((unsigned) pDs->spaceAvl);
memcpy((void *)newString, (void *) pDs->pString,
(size_t) pDs->length);
if (pDs->pString != pDs->staticSpace) {
free(pDs->pString);
}
pDs->pString = newString;
}
/*
* Copy the new string into the buffer at the end of the old
* one.
*/
for (dst = pDs->pString + pDs->length, end = string+length;
string < end; string++, dst++) {
*dst = tolower(*string);
}
*dst = 0;
pDs->length += length;
return pDs->pString;
}

View file

@ -1,73 +0,0 @@
/****************************************************************************
* Dynamic strings
****************************************************************************/
/*
* tcl.h --
*
* This header file describes the externally-visible facilities
* of the Tcl interpreter.
*
* Copyright (c) 1987-1994 The Regents of the University of California.
* Copyright (c) 1994-1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39
*/
#ifndef DSTRING_H
#define DSTRING_H
#ifdef __cplusplus
extern "C"
{
#endif
#define kDstringStaticSize 200
typedef struct DString {
char *pString; /* Points to beginning of string: either
* staticSpace below or a malloc'ed array. */
int length; /* Number of non-NULL characters in the
* string. */
int spaceAvl; /* Total number of bytes available for the
* string and its terminating NULL char. */
char staticSpace[kDstringStaticSize];
/* Space to use in common case where string
* is small. */
} DString;
#define DStringLength(dsPtr) ((dsPtr)->length)
#define DStringValue(dsPtr) ((dsPtr)->pString)
#define DStringTrunc DStringSetLength
char*
DStringAppend(DString* dsPtr,
const char* string,
int length);
void
DStringFree(DString* dsPtr);
void
DStringInit(DString* dsPtr);
void
DStringSetLength(DString* dsPtr,
int length);
void
DStringSprintf(DString* pDs,
const char* pFormat,
...);
char*
DStringAppendLowerCase(DString* pDs,
const char* pIn,
int length);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,483 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "file_util.h"
#include "str_util.h"
#include "strlist_util.h"
char *FilePath_ConcatA(const char *path, const char *name)
{
assert(path && name);
if (!path || !name) return NULL;
if (str_endswith(path, DIR_SEP_STR))
return str_cat(path, name);
else
return str_cat3(path, DIR_SEP_STR, name);
}
const char *FilePath_GetBaseName(const char *path)
{
const char *fileBaseName = (const char*)strrchr(path, DIR_SEP_CHAR);
if (NULL == fileBaseName)
fileBaseName = path;
else
++fileBaseName;
return fileBaseName;
}
char *FilePath_GetDir(const char *path)
{
char *lastSep;
char *dir = str_dup(path);
if (!dir) return NULL;
lastSep = (char*)strrchr(dir, DIR_SEP_CHAR);
if (NULL != lastSep)
*lastSep = 0;
return dir;
}
/* TODO: handle TCHAR (UNICODE) properly by converting to path to unicode
if UNICODE or _UNICODE symbols are defined */
/* Start iteration of all files 'path'. 'path' should be a directory
name but doesn't have to end with "\" (we append it if it's missing)
Retuns NULL if there was an error.
When no longer needed, the result should be deleted with
'DirIter_Delete'.
*/
DirIterState *DirIter_New(const char *path)
{
DirIterState *state;
assert(path);
if (!path)
return NULL;
state = SA(DirIterState);
if (!state)
return NULL;
/* TODO: made state->cleanPath cannonical */
state->cleanPath = str_dup(path);
state->iterPath = FilePath_ConcatA(path, "*");
if (!state->cleanPath || !state->iterPath) {
DirIter_Delete(state);
return NULL;
}
state->dir = INVALID_HANDLE_VALUE;
return state;
}
/* Get information about next file in a directory.
Returns FALSE on end of iteration (or error). */
BOOL DirIter_Next(DirIterState *s)
{
BOOL found;
if (INVALID_HANDLE_VALUE == s->dir) {
s->dir = FindFirstFileA(s->iterPath, &(s->fileInfo));
if (INVALID_HANDLE_VALUE == s->dir)
return FALSE;
goto CheckFile;
}
for(;;) {
found = FindNextFileA(s->dir, &(s->fileInfo));
if (!found)
return FALSE;
else
CheckFile:
return TRUE;
}
}
/* Free memory associated with 'state' */
void DirIter_Delete(DirIterState *state)
{
if (state) {
free(state->cleanPath);
free(state->iterPath);
}
free(state);
}
static FileList *FileList_New(char *dir)
{
FileList *fl;
assert(dir);
fl = SAZ(FileList);
if (!fl)
return NULL;
fl->dirName = str_dup(dir);
if (!fl->dirName) {
free((void*)fl);
return NULL;
}
return fl;
}
static BOOL FileList_InsertFileInfo(FileList *fl, FileInfo *fi)
{
int real_count;
FileInfo *last_fi;
assert(fl);
if (!fl)
return FALSE;
assert(fi);
if (!fi)
return FALSE;
/* TODO: use scheme where we also track of the last node, so that
insert is O(1) and not O(n) */
assert(!fi->next);
fi->next = NULL;
if (!fl->first) {
assert(0 == fl->filesCount);
fl->first = fi;
fl->filesCount = 1;
return TRUE;
}
last_fi = fl->first;
assert(last_fi);
real_count = 1;
while (last_fi->next) {
++real_count;
last_fi = last_fi->next;
}
assert(real_count == fl->filesCount);
last_fi->next = fi;
++fl->filesCount;
return TRUE;
}
void FileInfo_Delete(FileInfo *fi)
{
if (!fi) return;
free(fi->name);
free(fi->path);
free(fi);
}
static FileInfo *FileInfo_New(char *path, char *name, int64 size, DWORD attr, FILETIME *modificationTime)
{
FileInfo *fi;
assert(name);
if (!name)
return NULL;
assert(modificationTime);
if (!modificationTime)
return NULL;
fi = SAZ(FileInfo);
if (!fi)
return NULL;
fi->name = str_dup(name);
fi->path = str_dup(path);
if (!fi->name || !fi->path) {
FileInfo_Delete(fi);
return NULL;
}
fi->size = size;
fi->attr = attr;
fi->modificationTime = *modificationTime;
return fi;
}
static FileInfo* FileInfo_FromDirIterState(DirIterState *state)
{
FileInfo * fi;
WIN32_FIND_DATAA *fd;
char * fileName;
int64 size;
char * filePath;
assert(state);
if (!state) return NULL;
fd = &state->fileInfo;
size = fd->nFileSizeHigh;
size = size >> 32;
size += fd->nFileSizeLow;
/* TODO: handle UNICODE */
fileName = fd->cFileName;
filePath = FilePath_ConcatA(state->cleanPath, fileName);
fi = FileInfo_New(filePath, fileName, size, fd->dwFileAttributes, &fd->ftLastWriteTime);
return fi;
}
BOOL FileInfo_IsFile(FileInfo *fi)
{
DWORD attr;
assert(fi);
if (!fi) return
FALSE;
attr = fi->attr;
if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
return TRUE;
return FALSE;
}
int FileInfo_IsDir(FileInfo *fi)
{
DWORD attr;
assert(fi);
if (!fi) return
FALSE;
attr = fi->attr;
if (attr & FILE_ATTRIBUTE_DIRECTORY)
return TRUE;
return FALSE;
}
static int FileList_Append(char *path, FileList *fl, int (*filter)(FileInfo *))
{
FileInfo * fi;
DirIterState * state;
int shouldInsert;
if (!path || !fl)
return 0;
state = DirIter_New(path);
if (!state) {
return 0;
}
/* TODO: handle errors from DirIter_Next */
while (DirIter_Next(state)) {
fi = FileInfo_FromDirIterState(state);
if (!fi) {
DirIter_Delete(state);
return 0;
}
if (fi) {
shouldInsert = 1;
if (filter && !(*filter)(fi))
shouldInsert = 0;
if (shouldInsert)
FileList_InsertFileInfo(fl, fi);
}
}
DirIter_Delete(state);
return 1;
}
/* Return a list of files/directories in a 'path'. Use filter function
to filter out files that should not get included (return 0 from the function
to exclude it from the list.
Returns NULL in case of an error.
Use FileList_Delete() to free up all memory associated with this data.
Doesn't recurse into subdirectores, use FileList_GetRecursive for that. */
/* TODO: 'filter' needs to be implemented. */
/* TODO: add 'filterRegexp' argument that would allow filtering via regular
expression */
FileList *FileList_Get(char* path, int (*filter)(FileInfo *))
{
FileList * fl;
int ok;
if (!path)
return NULL;
/* TODO: should I expand "." ? */
fl = FileList_New(path);
if (!fl)
return NULL;
ok = FileList_Append(path, fl, filter);
if (!ok) {
FileList_Delete(fl);
return NULL;
}
return fl;
}
/* Like FileList_Get() except recurses into sub-directories */
/* TODO: 'filter' needs to be implemented. */
/* TODO: add 'filterRegexp' argument that would allow filtering via regular
expression */
FileList *FileList_GetRecursive(char* path, int (*filter)(FileInfo *))
{
StrList *toVisit = NULL;
FileList *fl = NULL;
assert(0);
/* TODO: clearly, implement */
return NULL;
}
void FileList_Delete(FileList *fl)
{
FileInfo *fi;
FileInfo *fi_next;
if (!fl)
return;
fi = fl->first;
while (fi) {
fi_next = fi->next;
FileInfo_Delete(fi);
fi = fi_next;
}
free((void*)fl->dirName);
free((void*)fl);
}
int FileList_Len(FileList *fl)
{
return fl->filesCount;
}
FileInfo *FileList_GetFileInfo(FileList *fl, int file_no)
{
FileInfo *fi;
if (!fl)
return NULL;
if (file_no >= fl->filesCount)
return NULL;
fi = fl->first;
while (file_no > 0) {
assert(fi->next);
if (!fi->next)
return NULL;
fi = fi->next;
--file_no;
}
return fi;
}
#ifdef _WIN32
size_t file_size_get(const char *file_path)
{
int fOk;
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
if (NULL == file_path)
return INVALID_FILE_SIZE;
fOk = GetFileAttributesExA(file_path, GetFileExInfoStandard, (void*)&fileInfo);
if (!fOk)
return INVALID_FILE_SIZE;
return (size_t)fileInfo.nFileSizeLow;
}
#else
#include <sys/types.h>
#include <sys/stat.h>
size_t file_size_get(const char *file_path)
{
struct stat stat_buf;
int res;
unsigned long size;
if (NULL == file_path)
return INVALID_FILE_SIZE;
res = stat(file_path, &stat_buf);
if (0 != res)
return INVALID_FILE_SIZE;
size = (size_t)stat_buf.st_size;
return size;
}
#endif
#ifdef _WIN32
char *file_read_all(const char *file_path, size_t *file_size_out)
{
DWORD size, size_read;
HANDLE h;
char * data = NULL;
int f_ok;
h = CreateFileA(file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return NULL;
size = GetFileSize(h, NULL);
if (-1 == size)
goto Exit;
/* allocate one byte more and 0-terminate just in case it's a text
file we'll want to treat as C string. Doesn't hurt for binary
files */
data = (char*)malloc(size + 1);
if (!data)
goto Exit;
data[size] = 0;
f_ok = ReadFile(h, data, size, &size_read, NULL);
if (!f_ok) {
free(data);
data = NULL;
}
*file_size_out = (size_t)size;
Exit:
CloseHandle(h);
return data;
}
#else
/* TODO: change unsinged long to int64 or size_t */
char *file_read_all(const char *file_path, size_t *file_size_out)
{
FILE *fp = NULL;
char *data = NULL;
size_t read;
size_t file_size = file_size_get(file_path);
if (INVALID_FILE_SIZE == file_size)
return NULL;
data = (char*)malloc(file_size + 1);
if (!data)
goto Exit;
data[file_size] = 0;
fp = fopen(file_path, "rb");
if (!fp)
goto Error;
read = fread((void*)data, 1, file_size, fp);
if (ferror(fp))
goto Error;
assert(read == file_size);
if (read != file_size)
goto Error;
fclose(fp);
return data;
Error:
if (fp)
fclose(fp);
free((void*)data);
return NULL;
}
#endif
#ifdef _WIN32
BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len)
{
DWORD size;
HANDLE h;
BOOL f_ok;
h = CreateFile(file_path, GENERIC_WRITE, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return FALSE;
f_ok = WriteFile(h, data, (DWORD)data_len, &size, NULL);
assert(!f_ok || ((DWORD)data_len == size));
CloseHandle(h);
return f_ok;
}
#else
// not supported
#endif

View file

@ -1,61 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef FILE_UTILS_H_
#define FILE_UTILS_H_
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct DirIterState {
char * fileName;
char * cleanPath;
char * iterPath;
WIN32_FIND_DATAA fileInfo;
HANDLE dir;
} DirIterState;
typedef struct FileInfo {
struct FileInfo *next;
char * path; /* full path of the file e.g. c:\foo\bar.txt */
char * name; /* just the name part e.g. bar.txt, points into 'path' */
int64 size;
FILETIME modificationTime;
FILETIME accessTime;
FILETIME createTime;
DWORD attr;
/* TODO: file attributes like file type etc. */
} FileInfo;
typedef struct FileList {
FileInfo * first;
char * dirName; /* directory where files lives e.g. c:\windows\ */
int filesCount;
} FileList;
DirIterState * DirIter_New(const char *path);
BOOL DirIter_Next(DirIterState *s);
void DirIter_Delete(DirIterState *state);
BOOL FileInfo_IsFile(FileInfo *fi);
BOOL FileInfo_IsDir(FileInfo *fi);
void FileInfo_Delete(FileInfo *fi);
FileList * FileList_Get(char* path, int (*filter)(FileInfo *));
FileList * FileList_GetRecursive(char* path, int (*filter)(FileInfo *));
void FileList_Delete(FileList *fl);
int FileList_Len(FileList *fl);
FileInfo * FileList_GetFileInfo(FileList *fl, int file_no);
const char * FilePath_GetBaseName(const char *path);
char * FilePath_GetDir(const char *path);
char * file_read_all(const char *file_path, size_t *file_size_out);
size_t file_size_get(const char *file_path);
BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,225 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "geom_util.h"
/* Return true if 'r1' and 'r2' intersect. Put the intersect area into
'rIntersectOut'.
Return false if there is no intersection. */
int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut)
{
int x1s, x1e, x2s, x2e;
int y1s, y1e, y2s, y2e;
int xIntersectS, xIntersectE;
int yIntersectS, yIntersectE;
assert(r1 && r2 && rIntersectOut);
if (!r1 || !r2 || !rIntersectOut)
return 0;
x1s = r1->x;
x2s = r2->x;
x1e = x1s + r1->dx;
x2e = x2s + r2->dx;
/* { } visualizes r1 and | | visualizes r2 */
/* problem is symmetric, so reduce the number of different cases by
consistent ordering where r1 is always before r2 in axis-x */
if (x2s < x1s) {
swap_int(&x1s, &x2s);
swap_int(&x1e, &x2e);
}
/* case of non-overlapping rectangles i.e.:
{ } | | */
if (x2s > x1e)
return 0;
/* partially overlapped i.e.:
{ | } |
and one inside the other i.e.:
{ | | } */
assert(x2s >= x1s);
assert(x2s <= x1e);
xIntersectS = x2s;
xIntersectE = MinInt(x1e, x2e);
assert(xIntersectE >= xIntersectS);
/* the logic for y is the same */
y1s = r1->y;
y2s = r2->y;
y1e = y1s + r1->dy;
y2e = y2s + r2->dy;
if (y2s < y1s) {
swap_int(&y1s, &y2s);
swap_int(&y1e, &y2e);
}
if (y2s > y1e)
return 0;
assert(y2s >= y1s);
assert(y2s <= y1e);
yIntersectS = y2s;
yIntersectE = MinInt(y1e, y2e);
rIntersectOut->x = xIntersectS;
rIntersectOut->y = yIntersectS;
assert(xIntersectE >= xIntersectS);
assert(yIntersectE >= yIntersectS);
rIntersectOut->dx = xIntersectE - xIntersectS;
rIntersectOut->dy = yIntersectE - yIntersectS;
return 1;
}
void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye)
{
assert(rOut);
if (!rOut)
return;
assert(xs <= xe);
assert(ys <= ye);
rOut->x = xs;
rOut->y = ys;
rOut->dx = xe - xs;
rOut->dy = ye - ys;
}
void RectD_FromRectI(RectD *rOut, RectI *rIn)
{
rOut->x = (double)rIn->x;
rOut->y = (double)rIn->y;
rOut->dx = (double)rIn->dx;
rOut->dy = (double)rIn->dy;
}
int intFromDouble (double d) {
double i1 = (int) d;
double i2 = i1 + 1;
if (d - i1 < i2 - d)
return i1;
else
return i2;
}
void RectI_FromRectD(RectI *rOut, RectD *rIn)
{
rOut->x = intFromDouble(rIn->x);
rOut->y = intFromDouble(rIn->y);
rOut->dx = intFromDouble(rIn->dx);
rOut->dy = intFromDouble(rIn->dy);
}
void RectD_Copy(RectD *rOut, RectD *rIn) {
rOut->x = (double)rIn->x;
rOut->y = (double)rIn->y;
rOut->dx = (double)rIn->dx;
rOut->dy = (double)rIn->dy;
}
void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye)
{
assert(rOut);
if (!rOut)
return;
if (xs > xe)
swap_double(&xs, &xe);
if (ys > ye)
swap_double(&ys, &ye);
rOut->x = xs;
rOut->y = ys;
rOut->dx = xe - xs;
assert(rOut->dx >= 0.0);
rOut->dy = ye - ys;
assert(rOut->dy >= 0.0);
}
/* Return TRUE if point 'x'/'y' is inside rectangle 'r' */
int RectI_Inside(RectI *r, int x, int y)
{
if (x < r->x)
return FALSE;
if (x > r->x + r->dx)
return FALSE;
if (y < r->y)
return FALSE;
if (y > r->y + r->dy)
return FALSE;
return TRUE;
}
#ifndef NDEBUG
void RectI_AssertEqual(RectI *rIntersect, RectI *rExpected)
{
assert(rIntersect->x == rExpected->x);
assert(rIntersect->y == rExpected->y);
assert(rIntersect->dx == rExpected->dx);
assert(rIntersect->dy == rExpected->dy);
}
void u_RectI_Intersect(void)
{
int i, dataLen;
RectI r1, r2, rIntersect, rExpected, rExpectedSwaped;
int doIntersect, doIntersectExpected;
struct SRIData {
int x1s, x1e, y1s, y1e;
int x2s, x2e, y2s, y2e;
int intersect;
int i_xs, i_xe, i_ys, i_ye;
} testData[] = {
{ 0,10, 0,10, 0,10, 0,10, 1, 0,10, 0,10 }, /* complete intersect */
{ 0,10, 0,10, 20,30,20,30, 0, 0, 0, 0, 0 }, /* no intersect */
{ 0,10, 0,10, 5,15, 0,10, 1, 5,10, 0,10 }, /* { | } | */
{ 0,10, 0,10, 5, 7, 0,10, 1, 5, 7, 0,10 }, /* { | | } */
{ 0,10, 0,10, 5, 7, 5, 7, 1, 5, 7, 5, 7 },
{ 0,10, 0,10, 5, 15,5,15, 1, 5,10, 5,10 },
};
dataLen = dimof(testData);
for (i = 0; i < dataLen; i++) {
struct SRIData *curr;
curr = &(testData[i]);
RectI_FromXY(&rExpected, curr->i_xs, curr->i_xe, curr->i_ys, curr->i_ye);
RectI_FromXY(&rExpectedSwaped, curr->i_ys, curr->i_ye, curr->i_xs, curr->i_xe);
RectI_FromXY(&r1, curr->x1s, curr->x1e, curr->y1s, curr->y1e);
RectI_FromXY(&r2, curr->x2s, curr->x2e, curr->y2s, curr->y2e);
doIntersectExpected = curr->intersect;
doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
assert(doIntersect == doIntersectExpected);
if (doIntersect)
RectI_AssertEqual(&rIntersect, &rExpected);
/* if we swap rectangles, the results should be the same */
RectI_FromXY(&r2, curr->x1s, curr->x1e, curr->y1s, curr->y1e);
RectI_FromXY(&r1, curr->x2s, curr->x2e, curr->y2s, curr->y2e);
doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
assert(doIntersect == doIntersectExpected);
if (doIntersect)
RectI_AssertEqual(&rIntersect, &rExpected);
/* if we swap x with y coordinates in a rectangle, results should be the same */
RectI_FromXY(&r1, curr->y1s, curr->y1e, curr->x1s, curr->x1e);
RectI_FromXY(&r2, curr->y2s, curr->y2e, curr->x2s, curr->x2e);
doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
assert(doIntersect == doIntersectExpected);
if (doIntersect)
RectI_AssertEqual(&rIntersect, &rExpectedSwaped);
/* swap both rectangles and x with y, results should be the same */
RectI_FromXY(&r2, curr->y1s, curr->y1e, curr->x1s, curr->x1e);
RectI_FromXY(&r1, curr->y2s, curr->y2e, curr->x2s, curr->x2e);
doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
assert(doIntersect == doIntersectExpected);
if (doIntersect)
RectI_AssertEqual(&rIntersect, &rExpectedSwaped);
}
}
#endif

View file

@ -1,73 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef GEOM_UTIL_H_
#define GEOM_UTIL_H_
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct RectI {
int x, y;
int dx, dy;
} RectI;
typedef struct RectD {
double x,y;
double dx,dy;
} RectD;
int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut);
void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye);
int RectI_Inside(RectI *r, int x, int y);
void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye);
void RectD_FromRectI(RectD *rOut, RectI *rIn);
void RectI_FromRectD(RectI *rOut, RectD *rIn);
void RectD_Copy(RectD *rOut, RectD *rIn);
void u_RectI_Intersect(void);
#ifdef __cplusplus
}
#endif
/* allow using from both C and C++ code */
#ifdef __cplusplus
class PointD {
public:
PointD() { x = 0; y = 0; }
PointD(double _x, double _y) { x = _x; y = _y; }
void set(double _x, double _y) { x = _x; y = _y; }
double x;
double y;
};
class SizeI {
public:
SizeI(int _dx, int _dy) { dx = _dx; dy = _dy; }
void set(int _dx, int _dy) { dx = _dx; dy = _dy; }
int dx;
int dy;
};
class SizeD {
public:
SizeD(double dx, double dy) { m_dx = dx; m_dy = dy; }
SizeD(int dx, int dy) { m_dx = (double)dx; m_dy = (double)dy; }
SizeD(SizeI si) { m_dx = (double)si.dx; m_dy = (double)si.dy; }
SizeD() { m_dx = 0; m_dy = 0; }
int dxI() { return (int)m_dx; }
int dyI() { return (int)m_dy; }
double dx() { return m_dx; }
double dy() { return m_dy; }
void setDx(double dx) { m_dx = dx; }
void setDy(double dy) { m_dy = dy; }
SizeI size() { return SizeI((int)dx(), (int)dy()); } /* @note: int casts */
private:
double m_dx;
double m_dy;
};
#endif
#endif

View file

@ -1,160 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "log_util.h"
#include "str_util.h"
/* Simple logging. 'slog' stands for "simple logging". I figured that 'log'
is a very common name so used something else, but still short as a prefix
for API names */
/* TODO: slogfmt(const char *fmt, ...) */
/* TODO: extend to more than one file, by keeping a list of file names */
const TCHAR * g_cur_fileName = NULL;
/* initialize logging system, should be called before any logging calls */
BOOL slog_init(void)
{
/* do nothing yet */
return TRUE;
}
/* deinitialize logging system. Should be called before the program quits */
void slog_deinit(void)
{
slog_file_log_stop(NULL);
}
/* start logging to a file 'fileName'. From now on until slog_file_log_stop()
all slog* logging will also go to a file. If a file of that name already
exists, it'll overwrite it. */
BOOL slog_file_log_start(const TCHAR *fileName)
{
if (!fileName) return FALSE;
g_cur_fileName = tstr_dup(fileName);
DeleteFile(fileName);
return TRUE;
}
/* like 'slog_file_log_start' but will create a unique file based on 'fileName'.
If a 'fileName' has extension, it'll try the first available
'$file-$NNN.$ext' file (e.g. "my-app-log-000.txt") if 'fileName' is "my-app-log.txt"
If there is no extension, it'll be '$file-$NNN' */
int slog_file_log_unique_start(const TCHAR *fileName)
{
assert(0); /* not implemented */
return FALSE;
}
void slog_file_log_stop(const TCHAR *fileName)
{
/* 'fileName' is currently unused. The idea is that it should match the
name given to slog_file_log_start */
if (g_cur_fileName) {
free((void*)g_cur_fileName);
g_cur_fileName = NULL;
}
}
/* log 'txt' to all currently enabled loggers */
void slog_str(const char *txt)
{
DWORD to_write_cb;
DWORD written_cb;
int f_ok;
HANDLE fh;
if (!txt) return;
if (!g_cur_fileName) return;
/* we're using this inefficient way of re-opening the file for each
log so that we can also watch this file life using tail-like program */
fh = CreateFile(g_cur_fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == fh)
return;
SetFilePointer(fh, 0, NULL, FILE_END);
to_write_cb = (DWORD)strlen(txt);
f_ok = WriteFile(fh, (void*)txt, to_write_cb, &written_cb, NULL);
assert(f_ok && (written_cb == to_write_cb));
CloseHandle(fh);
}
void slog_str_printf(const char *format, ...)
{
char * tmp;
va_list args;
va_start(args, format);
tmp = str_printf_args(format, args);
va_end(args);
if (!tmp) return;
slog_str(tmp);
free(tmp);
}
static WCHAR* last_error_as_wstr(void)
{
WCHAR *msgBuf = NULL;
WCHAR *copy;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &msgBuf, 0, NULL);
if (!msgBuf) return NULL;
copy = wstr_dup(msgBuf);
LocalFree(msgBuf);
return copy;
}
void slog_last_error(const char *optional_prefix)
{
WCHAR *txt = last_error_as_wstr();
if (!txt) return;
slog_str(optional_prefix);
slog_wstr_nl(txt);
free(txt);
}
/* TODO: converting by casting isn't always correct but here we don't care much */
char *wstr_to_str(const WCHAR *txt)
{
char *txt_copy, *tmp;
if (!txt) return NULL;
txt_copy = (char*)malloc(tstr_len(txt) + 1);
if (!txt_copy) return NULL;
tmp = txt_copy;
while (*txt) {
*tmp++ = (char)*txt++;
}
*tmp = 0;
return txt_copy;
}
void slog_wstr(const WCHAR *txt)
{
char *txt_copy;
txt_copy = wstr_to_str(txt);
if (!txt_copy) return;
slog_str(txt_copy);
free(txt_copy);
}
/* log 'txt' to all currently enabled loggers and add newline */
void slog_str_nl(const char *txt)
{
/* TODO: given the 'reopen the file each time' implementation of
slgotxt, this should be optimized */
slog_str(txt);
slog_str("\n");
}
void slog_wstr_nl(const WCHAR *txt)
{
slog_wstr(txt);
slog_wstr(_T("\n"));
}

View file

@ -1,23 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef LOG_UTIL_H_
#define LOG_UTIL_H_
#include "base_util.h"
#include "tstr_util.h"
BOOL slog_init(void);
void slog_deinit(void);
BOOL slog_file_log_start(const TCHAR *fileName);
void slog_file_log_stop(const TCHAR *fileName);
void slog_str(const char *txt);
void slog_str_printf(const char *format, ...);
void slog_str_nl(const char *txt);
void slog_last_error(const char *optional_prefix);
void slog_wstr(const WCHAR *txt);
void slog_wstr_nl(const WCHAR *txt);
#endif

View file

@ -1,76 +0,0 @@
OUTDIR=obj-dummy
CC=cl.exe
VALID_TARGET=no
!if "$(TARGET)"=="rel"
OUTDIR=obj-win-rel
CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /MD /Ox
LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
VALID_TARGET=yes
!endif
!if "$(TARGET)"=="rel-unicode"
OUTDIR=obj-win-rel-unicode
CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /D "UNICODE" /MD /Ox
LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
VALID_TARGET=yes
!endif
!if "$(TARGET)"=="dbg"
OUTDIR=obj-win-dbg
CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /MDd /Od
VALID_TARGET=yes
!endif
!if "$(TARGET)"=="dbg-unicode"
OUTDIR=obj-win-dbg-unicode
CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /D "UNICODE" /MDd /Od
VALID_TARGET=yes
!endif
O=$(OUTDIR)
CFLAGS = $(CFLAGS) /nologo /c
CFLAGS = $(CFLAGS) /D "WIN32" /D "_WIN32_WINNT=0x0500"
CFLAGS = $(CFLAGS) /W3 /Zc:forScope /Zc:wchar_t /GR /Zi
CFLAGS = $(CFLAGS) /I.
LIBS = $(LIBS) kernel32.lib advapi32.lib comctl32.lib comdlg32.lib \
shell32.lib user32.lib gdi32.lib
LD = link.exe
LDFLAGS = $(LDFLAGS) /nologo /DEBUG
TEST_FILE_UTIL_OBJS=$(O)\base_util.obj $(O)\file_util.obj $(O)\geom_util.obj \
$(O)\prefs_util.obj $(O)\netstr.obj $(O)\str_util.obj $(O)\WinUtil.obj \
$(O)\win_util.obj $(O)\wstr_util.obj \
$(O)\test_file_util.obj
TEST_FILE_UTIL_EXE=$(O)\test_file_util.exe
TEST_FILE_UTIL_PDB=$(O)\test_file_util.pdb
!if "$(VALID_TARGET)"=="yes"
all: $(OUTDIR) $(TEST_FILE_UTIL_EXE)
$(OUTDIR): force
@if not exist $(OUTDIR) mkdir $(OUTDIR)
clean: force
-rmdir /S /Q $(OUTDIR)
!else
all clean: force
@echo TARGET must be set to: rel, dbg, rel-unicode or dbg-unicode
!endif
$(TEST_FILE_UTIL_EXE): $(TEST_FILE_UTIL_OBJS)
$(LD) $(LDFLAGS) /OUT:$@ \
/PDB:$(TEST_FILE_UTIL_PDB) \
$** $(LIBS) /SUBSYSTEM:CONSOLE /MACHINE:X86
.cpp{$(OUTDIR)}.obj::
$(CC) $(CFLAGS) -Fo$(OUTDIR)\ $<
.c{$(OUTDIR)}.obj::
$(CC) $(CFLAGS) -Fo$(OUTDIR)\ $<
force: ;

View file

@ -1,634 +0,0 @@
/*++
Copyright (c) 2003 Microsoft Corporation
Abstract:
Helper functions for HIDPI/Landscape support.
--*/
#include "ms_ui_helper.h"
HIDPI_ENABLE;
BOOL HIDPI_StretchBitmap(
HBITMAP* phbm,
int cxDstImg,
int cyDstImg,
int cImagesX,
int cImagesY
)
{
BOOL fRet = FALSE;
HBITMAP hbmNew;
BITMAP bm;
HDC hdcSrc, hdcDst, hdcScreen;
HBITMAP hbmOldSrc, hbmOldDst;
int cxSrcImg, cySrcImg;
int i, j, xDest, yDest, xBmp, yBmp;
if (!phbm || !*phbm || (cxDstImg == 0 && cyDstImg == 0) || (cImagesX == 0 || cImagesY == 0))
goto donestretch;
if ((sizeof(bm) != GetObject(*phbm, sizeof(bm), &bm)))
goto donestretch;
// If you hit this ASSERT, that mean your passed in image count in row and
// the column number of images is not correct.
// ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));
cxSrcImg = bm.bmWidth / cImagesX;
cySrcImg = bm.bmHeight / cImagesY;
if (cxSrcImg == cxDstImg && cySrcImg == cyDstImg)
{
fRet = TRUE;
goto donestretch;
}
if (cxDstImg == 0)
cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg);
else if (cyDstImg == 0)
cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg);
hdcSrc = CreateCompatibleDC(NULL);
hdcDst = CreateCompatibleDC(NULL);
hdcScreen = GetDC(NULL);
hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, *phbm);
hbmNew = CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY);
hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);
ReleaseDC(NULL, hdcScreen);
// BLAST!
for (j = 0, yDest = 0, yBmp = 0; j < cImagesY; j++, yDest += cyDstImg, yBmp += cySrcImg)
{
for (i = 0, xDest = 0, xBmp = 0; i < cImagesX; i++, xDest += cxDstImg, xBmp += cxSrcImg)
{
StretchBlt(hdcDst, xDest, yDest, cxDstImg, cyDstImg,
hdcSrc, xBmp, yBmp, cxSrcImg, cySrcImg,
SRCCOPY);
}
}
// Free allocated memory
SelectObject(hdcSrc, hbmOldSrc);
SelectObject(hdcDst, hbmOldDst);
DeleteDC(hdcSrc);
DeleteDC(hdcDst);
// Delete the passed in bitmap
DeleteObject(*phbm);
*phbm = hbmNew;
fRet = TRUE;
donestretch:
return fRet;
}
static BOOL HIDPI_StretchIcon_Internal(
HICON hiconIn,
HICON* phiconOut,
int cxIcon,
int cyIcon
)
{
ICONINFO iconinfo;
HDC hdc;
HBITMAP hbmImage, hbmMask;
HBITMAP hbmOld;
BOOL fDrawMaskOK;
BOOL fDrawImageOK;
*phiconOut = NULL;
hdc = CreateCompatibleDC(NULL);
hbmMask = CreateCompatibleBitmap(hdc, cxIcon, cyIcon);
hbmOld = (HBITMAP)SelectObject(hdc, hbmMask);
fDrawMaskOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK);
SelectObject(hdc, hbmOld);
hbmImage = CreateBitmap(cxIcon, cyIcon, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
hbmOld = (HBITMAP)SelectObject(hdc, hbmImage);
fDrawImageOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE);
SelectObject(hdc, hbmOld);
if (fDrawImageOK && fDrawMaskOK)
{
iconinfo.fIcon = TRUE;
iconinfo.hbmColor = hbmImage;
iconinfo.hbmMask = hbmMask;
*phiconOut = CreateIconIndirect(&iconinfo);
}
DeleteObject(hbmImage);
DeleteObject(hbmMask);
DeleteDC(hdc);
return (fDrawImageOK && fDrawMaskOK && *phiconOut != NULL) ? TRUE : FALSE;
}
BOOL HIDPI_StretchIcon(
HICON* phic,
int cxIcon,
int cyIcon
)
{
HICON hiconOut;
if (HIDPI_StretchIcon_Internal(*phic, &hiconOut, cxIcon, cyIcon))
{
DestroyIcon(*phic);
*phic = hiconOut;
return TRUE;
}
return FALSE;
}
BOOL HIDPI_GetBitmapLogPixels(
HINSTANCE hinst,
LPCTSTR lpbmp,
int* pnLogPixelsX,
int* pnLogPixelsY
)
{
BOOL fRet = FALSE;
HRSRC hResource;
HGLOBAL hResourceBitmap = NULL;
BITMAPINFO* pBitmapInfo;
int PelsPerMeterX, PelsPerMeterY;
*pnLogPixelsX = 0;
*pnLogPixelsY = 0;
hResource = FindResource(hinst, lpbmp, RT_BITMAP);
if (!hResource)
{
goto error;
}
hResourceBitmap = LoadResource(hinst, hResource);
if (!hResourceBitmap)
{
goto error;
}
pBitmapInfo = (BITMAPINFO*)LockResource(hResourceBitmap);
if (!pBitmapInfo)
{
goto error;
}
// There are at least three kind value of PslsPerMeter used for 96 DPI bitmap:
// 0 - the bitmap just simply doesn't set this value
// 2834 - 72 DPI
// 3780 - 96 DPI
// So any value of PslsPerMeter under 3780 should be treated as 96 DPI bitmap.
PelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter;
PelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter;
// The formula for converting PelsPerMeter to LogPixels(DPI) is:
// LogPixels = PelsPerMeter / 39.37
// ( PelsPerMeter : Pixels per meter )
// ( LogPixels : Pixels per inch )
// Note: We need to round up.
*pnLogPixelsX = (int)((PelsPerMeterX * 100 + 1968) / 3937);
*pnLogPixelsY = (int)((PelsPerMeterY * 100 + 1968) / 3937);
fRet = TRUE;
error:
return fRet;
}
HIMAGELIST HIDPI_ImageList_LoadImage(
HINSTANCE hinst,
LPCTSTR lpbmp,
int cx,
int cGrow,
COLORREF crMask,
UINT uType,
UINT uFlags
)
{
HBITMAP hbmImage = NULL;
HIMAGELIST piml = NULL;
BITMAP bm;
int cImages, cxImage, cy;
int BmpLogPixelsX, BmpLogPixelsY;
UINT flags;
if ((uType != IMAGE_BITMAP) || // Image type is not IMAGE_BITMAP
(cx == 0)) // Caller doesn't care about the dimensions of the image - assumes the ones in the file
{
piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
goto cleanup;
}
if (!HIDPI_GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY))
{
goto cleanup;
}
hbmImage = (HBITMAP)LoadImage(hinst, lpbmp, uType, 0, 0, uFlags);
if (!hbmImage || (sizeof(bm) != GetObject(hbmImage, sizeof(bm), &bm)))
{
goto cleanup;
}
// do we need to scale this image?
if (BmpLogPixelsX == g_HIDPI_LogPixelsX)
{
piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
goto cleanup;
}
cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, g_HIDPI_LogPixelsX);
// Bitmap width should be multiple integral of image width.
// If not, that means either your bitmap is wrong or passed in cx is wrong.
// ASSERT((bm.bmWidth % cxImage) == 0);
cImages = bm.bmWidth / cxImage;
cy = HIDPIMulDiv(bm.bmHeight, g_HIDPI_LogPixelsY, BmpLogPixelsY);
if ((g_HIDPI_LogPixelsX % BmpLogPixelsX) == 0)
{
HIDPI_StretchBitmap(&hbmImage, cx * cImages, cy, 1, 1);
}
else
{
// Here means the DPI is not integral multiple of standard DPI (96DPI).
// So if we stretch entire bitmap together, we are not sure each indivisual
// image will be stretch to right place. It is controled by StretchBlt().
// (for example, a 16 pixel icon, the first one might be stretch to 22 pixels
// and next one might be stretched to 20 pixels)
// What we have to do here is stretching indivisual image separately to make sure
// every one is stretched properly.
HIDPI_StretchBitmap(&hbmImage, cx, cy, cImages, 1);
}
flags = 0;
// ILC_MASK is important for supporting CLR_DEFAULT
if (crMask != CLR_NONE)
{
flags |= ILC_MASK;
}
// ILC_COLORMASK bits are important if we ever want to Merge ImageLists
if (bm.bmBits)
{
flags |= (bm.bmBitsPixel & ILC_COLORMASK);
}
// bitmap MUST be de-selected from the DC
// create the image list of the size asked for.
piml = ImageList_Create(cx, cy, flags, cImages, cGrow);
if (piml)
{
int added;
if (crMask == CLR_NONE)
{
added = ImageList_Add(piml, hbmImage, NULL);
}
else
{
added = ImageList_AddMasked(piml, hbmImage, crMask);
}
if (added < 0)
{
ImageList_Destroy(piml);
piml = NULL;
}
}
cleanup:
DeleteObject(hbmImage);
return piml;
}
int HIDPI_ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
{
int iRet;
int cxIcon, cyIcon;
HICON hiconStretched;
ImageList_GetIconSize(himl, &cxIcon, &cyIcon);
HIDPI_StretchIcon_Internal(hicon, &hiconStretched, cxIcon, cyIcon);
if (hiconStretched != NULL)
{
iRet = ImageList_ReplaceIcon(himl, i, hiconStretched);
DestroyIcon(hiconStretched);
}
else
{
iRet = ImageList_ReplaceIcon(himl, i, hicon);
}
return iRet;
}
BOOL HIDPI_RectangleInternal(HDC hdc, int nLeft, int nTop, int nRight, int nBottom, int nThickness)
{
int nOff = nThickness/2;
nLeft += nOff;
nTop += nOff;
nRight -= nOff;
nBottom -= nOff;
return Rectangle(hdc, nLeft, nTop, nRight, nBottom);
}
#define BORDERX_PEN 32
BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
{
HPEN hpenOld;
BOOL bRet;
hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
bRet = HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, GetSystemMetrics(SM_CXBORDER));
SelectObject(hdc, hpenOld);
return bRet;
}
BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
{
LOGPEN lpenSel;
HPEN hpenSel;
// Obtain current pen thickness
hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
return HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, lpenSel.lopnWidth.x);
}
BOOL HIDPI_PolylineInternal(HDC hdc, const POINT *lppt, int cPoints, int nStyle, int nThickness)
{
int i;
int nHOff = 0, nVOff = 0;
BOOL bRet = TRUE;
POINT pts[2];
if (! (nStyle & PS_BIAS_MASK))
{
// No drawing bias. Draw normally
return Polyline(hdc, lppt, cPoints);
}
// Make sure caller didn't try to get both a left and a right bias or both a down and an up bias
// ASSERT(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS));
// ASSERT(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS));
if (nStyle & PS_LEFTBIAS)
{
nHOff = -((nThickness-1)/2);
}
if (nStyle & PS_RIGHTBIAS)
{
nHOff = nThickness/2;
}
if (nStyle & PS_UPBIAS)
{
nVOff = -((nThickness-1)/2);
}
if (nStyle & PS_DOWNBIAS)
{
nVOff = nThickness/2;
}
for (i = 1; i < cPoints; i++)
{
// Use the two points that specify current line segment
memcpy(pts, &lppt[i-1], 2*sizeof(POINT));
if (abs(lppt[i].x - lppt[i-1].x) <= abs(lppt[i].y - lppt[i-1].y))
{
// Shift current line segment horizontally if abs(slope) >= 1
pts[0].x += nHOff;
pts[1].x += nHOff;
}
else
{
// Shift current line segment vertically if abs(slope) < 1
pts[0].y += nVOff;
pts[1].y += nVOff;
}
bRet = bRet && Polyline(hdc, pts, 2);
if (!bRet)
{
goto Error;
}
}
Error:
return bRet;
}
BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
{
HPEN hpenOld;
BOOL bRet;
hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
bRet = HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, GetSystemMetrics(SM_CXBORDER));
SelectObject(hdc, hpenOld);
return bRet;
}
BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
{
LOGPEN lpenSel;
HPEN hpenSel;
// Obtain current pen thickness
hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
return HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, lpenSel.lopnWidth.x);
}
//
// Called by RelayoutDialog to advance to the next item in the dialog template.
//
static LPBYTE WalkDialogData(LPBYTE lpData)
{
LPWORD lpWord = (LPWORD)lpData;
if (*lpWord == 0xFFFF)
{
return (LPBYTE)(lpWord + 2);
}
while (*lpWord != 0x0000)
{
lpWord++;
}
return (LPBYTE)(lpWord + 1);
}
//
// Post-processing step for each dialog item.
// Static controls and buttons: change text and bitmaps.
// Listboxes and combo boxes: ensures that the selected item is visible.
//
static void FixupDialogItem(
HINSTANCE hInst,
HWND hDlg,
LPDLGITEMTEMPLATE lpDlgItem,
LPWORD lpClass,
LPWORD lpData)
{
if (lpClass[0] == 0xFFFF)
{
switch (lpClass[1])
{
case 0x0080: // button
case 0x0082: // static
{
if (lpData[0] == 0xFFFF)
{
if (lpDlgItem->style & SS_ICON)
{
HICON hOld = (HICON)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_ICON, 0);
HICON hNew = LoadIcon(hInst, MAKEINTRESOURCE(lpData[1]));
SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hNew);
DestroyIcon(hOld);
}
else if (lpDlgItem->style & SS_BITMAP)
{
HBITMAP hOld = (HBITMAP)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_BITMAP, 0);
HBITMAP hNew = LoadBitmap(hInst, MAKEINTRESOURCE(lpData[1]));
SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hNew);
DeleteObject(hOld);
}
}
else // lpData[0] is not 0xFFFF (it's text).
{
SetDlgItemTextW(hDlg, lpDlgItem->id, (LPCTSTR)lpData);
}
}
break;
case 0x0083: // list box
{
INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_GETCURSEL, 0, 0);
if (nSel != LB_ERR)
{
SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_SETCURSEL, nSel, 0);
}
}
break;
case 0x0085: // combo box
{
INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_GETCURSEL, 0, 0);
if (nSel != CB_ERR)
{
SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_SETCURSEL, nSel, 0);
}
}
break;
}
}
}
BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate)
{
HRSRC hRsrc = FindResource((HMODULE)hInst, iddTemplate, RT_DIALOG);
INT nStatics = 0;
HGLOBAL hGlobal;
LPBYTE lpData;
LPDLGTEMPLATE lpTemplate;
HDWP hDWP;
int i;
LPDLGITEMTEMPLATE lpDlgItem;
HWND hwndCtl;
LPWORD lpClass;
WORD cbExtra;
if (hRsrc == NULL)
{
return FALSE;
}
hGlobal = LoadResource((HMODULE)hInst, hRsrc);
if (hGlobal == NULL)
{
return FALSE;
}
lpData = (LPBYTE)LockResource(hGlobal);
lpTemplate = (LPDLGTEMPLATE)lpData;
hDWP = BeginDeferWindowPos(lpTemplate->cdit);
//
// For more information about the data structures that we are walking,
// consult the DLGTEMPLATE and DLGITEMTEMPLATE documentation on MSDN.
//
lpData += sizeof(DLGTEMPLATE);
lpData = WalkDialogData(lpData); // menu
lpData = WalkDialogData(lpData); // class
lpData = WalkDialogData(lpData); // title
if (lpTemplate->style & DS_SETFONT)
{
lpData += sizeof(WORD); // font size.
lpData = WalkDialogData(lpData); // font face.
}
for (i = 0; i < lpTemplate->cdit; i++)
{
lpData = (LPBYTE) (((INT)lpData + 3) & ~3); // force to DWORD boundary.
lpDlgItem = (LPDLGITEMTEMPLATE)lpData;
hwndCtl = GetDlgItem(hDlg, lpDlgItem->id);
if (lpDlgItem->id == 0xFFFF)
{
nStatics++;
}
//
// Move the item around.
//
{
RECT r;
r.left = lpDlgItem->x;
r.top = lpDlgItem->y;
r.right = lpDlgItem->x + lpDlgItem->cx;
r.bottom = lpDlgItem->y + lpDlgItem->cy;
MapDialogRect(hDlg, &r);
DeferWindowPos(hDWP, hwndCtl, NULL,
r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER);
}
lpData += sizeof(DLGITEMTEMPLATE);
lpClass = (LPWORD)lpData;
lpData = WalkDialogData(lpData); // class
//
// Do some special handling for each dialog item (changing text,
// bitmaps, ensuring visible, etc.
//
FixupDialogItem(hInst, hDlg, lpDlgItem, lpClass, (LPWORD)lpData);
lpData = WalkDialogData(lpData); // title
cbExtra = *((LPWORD)lpData); // extra class data.
lpData += (cbExtra ? cbExtra : sizeof(WORD));
}
EndDeferWindowPos(hDWP);
return nStatics < 2 ? TRUE : FALSE;
}

View file

@ -1,348 +0,0 @@
/*++
Copyright (c) 2003 Microsoft Corporation
Module Name:
uihelper.h
Abstract:
Include file for HIDPI / orientation / font change helper functions.
--*/
#ifndef __UIHELPER_H__
#define __UIHELPER_H__
#include <windows.h>
#include <commctrl.h>
#include "ms_ui_shguim.h"
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
// HIDPI functions and constants.
////////////////////////////////////////////////////////////////////////////////
#ifndef ILC_COLORMASK
#define ILC_COLORMASK 0x00FE
#endif
//
// The two macros HIDPISIGN and HIDPIABS are there to ensure correct rounding
// for negative numbers passed into HIDPIMulDiv as x (we want -1.5 to round
// to -1, 2.5 to round to 2, etc). So we use the absolute value of x, and then
// multiply the result by the sign of x. Y and z should never be negative, as
// y is the dpi of the device (presumably 192 or 96), and z is always 96, as
// that is our original dpi we developed on.
//
#define HIDPISIGN(x) (((x)<0)?-1:1)
#define HIDPIABS(x) (((x)<0)?-(x):x)
#define HIDPIMulDiv(x,y,z) ((((HIDPIABS(x)*(y))+((z)>>1))/(z))*HIDPISIGN(x))
//
// Cached values of GetDeviceCaps(LOGPIXELSX/Y) for the screen DC.
//
EXTERN_C int g_HIDPI_LogPixelsX;
EXTERN_C int g_HIDPI_LogPixelsY;
//
// You need to define these somewhere in your .c files only if you make use of
// the scaling macros. (Defined in UIHelper.cpp).
//
#define HIDPI_ENABLE \
int g_HIDPI_LogPixelsX; \
int g_HIDPI_LogPixelsY;
//
// Scaling macros.
//
#define SCALEX(argX) (HIDPIMulDiv(argX,g_HIDPI_LogPixelsX,96))
#define SCALEY(argY) (HIDPIMulDiv(argY,g_HIDPI_LogPixelsY,96))
#define UNSCALEX(argX) (HIDPIMulDiv(argX,96,g_HIDPI_LogPixelsX))
#define UNSCALEY(argY) (HIDPIMulDiv(argY,96,g_HIDPI_LogPixelsY))
#define SCALERECT(rc) { rc.left = SCALEX(rc.left); rc.right = SCALEX(rc.right); rc.top = SCALEY(rc.top); rc.bottom = SCALEY(rc.bottom);}
#define SCALEPT(pt) { pt.x = SCALEX(pt.x); pt.y = SCALEY(pt.y);}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_InitScaling
//
// PURPOSE: Initializes g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY. This
// should be called once at the beginning of any HIDPI-aware application.
//
__inline void HIDPI_InitScaling()
{
HDC screen;
if( g_HIDPI_LogPixelsX )
return;
screen = GetDC(NULL);
g_HIDPI_LogPixelsX = GetDeviceCaps(screen, LOGPIXELSX);
g_HIDPI_LogPixelsY = GetDeviceCaps(screen, LOGPIXELSY);
ReleaseDC(NULL, screen);
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_StretchBitmap
//
// PURPOSE: Stretches a bitmap containing a grid of images. There are
// cImagesX images per row and cImagesY rows per bitmap. Each image is
// scaled individually, so that there are no artifacts with non-integral
// scaling factors. If the bitmap contains only one image, set cImagesX
// and cImagesY to 1.
//
// ON ENTRY:
// HBITMAP* phbm: a pointer to the bitmap to be scaled.
// INT cxDstImg: the width of each image after scaling.
// INT cyDstImg: the height of each image after scaling.
// INT cImagesX: the number of images per row. This value should
// evenly divide the width of the bitmap.
// INT cImagesY: the number of rows in the bitmap. This value should
// evenly divide the height of the bitmap.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
// If any scaling has occured, the bitmap pointed to by phbm is deleted
// and is replaced by a new bitmap handle.
//
BOOL HIDPI_StretchBitmap(
HBITMAP* phbm,
int cxDstImg,
int cyDstImg,
int cImagesX,
int cImagesY
);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_GetBitmapLogPixels
//
// PURPOSE: retrieves the DPI fields of the specified bitmap.
//
// ON ENTRY:
// HINSTANCE hinst: the HINSTANCE of the bitmap resource.
// LPCTSTR lpbmp: the ID of the bitmap resource. The MAKEINTRESOURCE
// macro can be used for integer IDs.
// INT* pnLogPixelsX: the returned value for the horizontal DPI field of
// the bitmap. This value is never less than 96.
// INT* pnLogPixelsY: the returned value for the vertical DPI field of
// the bitmap. This value is never less than 96.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
BOOL HIDPI_GetBitmapLogPixels(
HINSTANCE hinst,
LPCTSTR lpbmp,
int* pnLogPixelsX,
int* pnLogPixelsY
);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_StretchIcon
//
// PURPOSE: stretches an icon to the specified size on 4.21 devices and later.
// On 4.20 and previous revisions of the OS, this is a no-op.
//
// ON ENTRY:
// HICON* phic: the icon to stretch.
// INT cxIcon: the desired width of the icon.
// INT cyIcon: the desired height of the icon.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
// If any stretching occurred, the icon pointed to by phic is deleted and
// is replaced by a new icon handle.
//
BOOL HIDPI_StretchIcon(
HICON* phic,
int cxIcon,
int cyIcon
);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_ImageList_LoadImage
//
// PURPOSE: This function operates identically to ImageList_LoadImage, except
// that it first checks the DPI fields of the bitmap (using
// HIDPI_GetBitmapLogPixels); compares it to the DPI of the screen
// (using g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY), and performs scaling
// (using HIDPI_StretchBitmap) if the values are different.
//
// ON ENTRY:
// See the MSDN documentation for ImageList_LoadImage.
//
// ON EXIT:
// See the MSDN documentation for ImageList_LoadImage.
//
HIMAGELIST HIDPI_ImageList_LoadImage(
HINSTANCE hinst,
LPCTSTR lpbmp,
int cx,
int cGrow,
COLORREF crMask,
UINT uType,
UINT uFlags
);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_ImageList_ReplaceIcon
//
// PURPOSE: Replaces an icon in an ImageList, scaling it from its original size
// to the size of the images in the ImageList.
//
// ON ENTRY:
// See the MSDN documentation for ImageList_ReplaceIcon.
//
// ON EXIT:
// See the MSDN documentation for ImageList_ReplaceIcon.
//
int HIDPI_ImageList_ReplaceIcon(
HIMAGELIST himl,
int i,
HICON hicon
);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_ImageList_AddIcon
//
// PURPOSE: Adds an icon to an ImageList, scaling it from its original size
// to the size of the images in the ImageList.
//
// ON ENTRY:
// See the MSDN documentation for ImageList_AddIcon.
//
// ON EXIT:
// See the MSDN documentation for ImageList_AddIcon.
//
#define HIDPI_ImageList_AddIcon(himl, hicon) HIDPI_ImageList_ReplaceIcon(himl, -1, hicon)
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_Rectangle
//
// PURPOSE: Draws a rectangle using the currently selected pen. Drawing occurs
// completely within the drawing rectangle (the rectangle has an "inside
// frame" drawing style).
//
// ON ENTRY:
// HDC hdc: the display context of the drawing surface.
// INT nLeft: left bound of rectangle
// INT nTop: top bound of rectangle
// INT nRight: right bound of rectangle plus one.
// INT nBottom: bottom bound of rectangle plus one.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_BorderRectangle
//
// PURPOSE: Draws a rectangle with the system border pen. Drawing occurs
// completely within the drawing rectangle (the rectangle has an "inside
// frame" drawing style).
//
// ON ENTRY:
// HDC hdc: the display context of the drawing surface.
// INT nLeft: left bound of rectangle
// INT nTop: top bound of rectangle
// INT nRight: right bound of rectangle plus one.
// INT nBottom: bottom bound of rectangle plus one.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_Polyline
//
// PURPOSE: Draws a polyline using the currently selected pen. In addition,
// this function provides control over how the line will be drawn.
//
// ON ENTRY:
// HDC hdc: the display context of the drawing surface.
// const POINT* lppt: array of POINTS that specify line to draw.
// INT cPoints: number of points in array.
// INT nStyle: the style the pen should be drawn in. This may be an
// existing pen style, such as PS_SOLID, or one of the following styles:
//
// PS_LEFTBIAS PS_UPBIAS PS_UPLEFT
// PS_RIGHTBIAS PS_DOWNBIAS PS_DOWNRIGHT
//
// These styles indicate how the pen should "hang" from each line
// segment. By default, the pen is centered along the line, but with
// these line styles the developer can draw lines above, below, to the
// left or to the right of the line segment.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
#define PS_RIGHTBIAS 0x10
#define PS_LEFTBIAS 0x20
#define PS_DOWNBIAS 0x40
#define PS_UPBIAS 0x80
#define PS_DOWNRIGHT (PS_DOWNBIAS | PS_RIGHTBIAS)
#define PS_UPLEFT (PS_UPBIAS | PS_LEFTBIAS)
#define PS_BIAS_MASK (PS_RIGHTBIAS | PS_LEFTBIAS | PS_DOWNBIAS | PS_UPBIAS)
BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: HIDPI_BorderPolyline
//
// PURPOSE: Draws a polyline, but with the system border pen. In addition,
// this function provides control over how the line will be drawn.
//
// ON ENTRY:
// HDC hdc: the display context of the drawing surface.
// const POINT* lppt: array of POINTS that specify line to draw.
// INT cPoints: number of points in array.
// INT nStyle: the style the pen should be drawn in. See HIDPI_Polyline
// for more details.
//
// ON EXIT:
// Returns TRUE on success, FALSE on failure.
//
BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle);
////////////////////////////////////////////////////////////////////////////////
// Orientation functions.
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: RelayoutDialog
//
// PURPOSE: Re-lays out a dialog based on a dialog template. This function
// iterates through all the child window controls and does a SetWindowPos
// for each. It also does a SetWindowText for each static text control
// and updates the selected bitmap or icon in a static image control.
// This assumes that the current dialog and the new template have all the
// same controls, with the same IDCs.
//
// ON ENTRY:
// HINSTANCE hInst: the hInstance of the current module.
// HWND hDlg: the dialog to layout.
// LPCWSTR iddTemplate: the new template for the dialog (can use
// the MAKEINTRESOURCE macro).
//
// ON EXIT: TRUE if success; FALSE if failure (either the iddTemplate is
// invalid, or there are two or more IDC_STATICs in the template).
//
BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate);
#ifdef __cplusplus
}
#endif
#endif // __UIHELPER_H__

View file

@ -1,96 +0,0 @@
/*++
Copyright (c) 2003 Microsoft Corporation
Abstract:
Include file for SHGetUIMetric.
--*/
#ifndef __SHGUIM_H__
#define __SHGUIM_H__
#include <windows.h>
//
// Call RegisterWindowMessage on this string if you are interested in knowing
// when the UI metrics have changed. wParam will be 0, lParam will be one of the
// SHUIMETRICTYPE values to indicate what value has changed. Call SHGetUIMetrics
// to find out the new value.
//
#define SH_UIMETRIC_CHANGE TEXT("SH_UIMETRIC_CHANGE")
#if _MSC_VER >= 1400
#include <aygshell.h>
#else
//
// Enumeration of metrics you can ask for. Note that you will only receive a
// notification for SHUIM_FONTSIZE_POINT when any these three values changes.
//
typedef enum tagSHUIMETRIC
{
SHUIM_INVALID = 0, // Illegal
SHUIM_FONTSIZE_POINT, // Application font size (hundredths of a point) -- buffer is pointer to DWORD
SHUIM_FONTSIZE_PIXEL, // Application font size (in pixels) -- buffer is pointer to DWORD
SHUIM_FONTSIZE_PERCENTAGE, // Application font size as percentage of normal -- buffer is pointer to DWORD
} SHUIMETRIC;
typedef HRESULT (*PSHGETUIMETRICS)(SHUIMETRIC, PVOID, DWORD, DWORD*);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: SHGetUIMetrics
//
// PURPOSE: retrieves the shell's UI metrics. Although this function does not
// exist in the Pocket PC 2003 SDK, it exists AYGSHELL.DLL in newer
// versions of the Pocket PC. This function simply LoadLibrary's AYGSHELL
// and calls the function if it exists.
//
// ON ENTRY:
// SHUIMETRIC shuim: the metric to retrieve.
// PVOID pvBuffer: the retrieved data for the metric.
// DWORD cbBufferSize: the size of pvBuffer (should be sizeof(DWORD)).
// DWORD* pcbRequired: retrieves the minimum size of the buffer necessary
// to get the specified system UI metric. This can be NULL.
//
__inline HRESULT SHGetUIMetrics(SHUIMETRIC shuim, PVOID pvBuffer, DWORD cbBufferSize, DWORD *pcbRequired)
{
PSHGETUIMETRICS pSHGetUIMetrics = (PSHGETUIMETRICS)GetProcAddress(LoadLibrary(_T("AYGSHELL")), _T("SHGetUIMetrics"));
if (pSHGetUIMetrics)
{
return pSHGetUIMetrics(shuim, pvBuffer, cbBufferSize, pcbRequired);
}
else if (pvBuffer != NULL && cbBufferSize >= sizeof(DWORD))
{
//
// Not supported on this version of Pocket PC, so come up with a reasonable default.
//
LOGFONT lf;
HFONT hFont = (HFONT)GetStockObject(SYSTEM_FONT);
GetObject(hFont, sizeof(lf), &lf);
switch (shuim)
{
case SHUIM_FONTSIZE_POINT:
{
HDC hDC = GetDC(NULL);
int nDPI = GetDeviceCaps(hDC, LOGPIXELSY);
ReleaseDC(NULL, hDC);
*(DWORD*)pvBuffer = (-lf.lfHeight * 7200) / nDPI;
break;
}
case SHUIM_FONTSIZE_PIXEL: *(DWORD*)pvBuffer = -lf.lfHeight; break;
case SHUIM_FONTSIZE_PERCENTAGE: *(DWORD*)pvBuffer = 100; break;
}
}
else if (pcbRequired)
{
*pcbRequired = sizeof(DWORD);
}
return S_OK;
}
#endif
#endif

View file

@ -1,271 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "tstr_util.h"
#include "netstr.h"
/* Implements djb idea of net strings */
/* Return the number of digits needed to represents a given number in base 10
string representation.
*/
size_t digits_for_number(int num)
{
size_t digits = 1;
/* negative numbers need '-' in front of them */
if (num < 0) {
++digits;
num = -num;
}
while (num >= 10)
{
++digits;
num = num / 10;
}
return digits;
}
/* Netstring format is a safe, easy and mostly human readable format for
serializing strings (well, any binary data). Netstring format is:
- a byte length of the data as a string
- ':' (single character)
- data
- ',' (single character)
e.g. "foo" is encoded as "3:foo,"
I learned about netstring format from djb (http://cr.yp.to/proto/netstrings.txt)
*/
size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch)
{
size_t total_len_cch;
/* 2 is for ':" and ',' */
total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2;
return total_len_cch * sizeof(TCHAR);
}
/* Return number of bytes needed to serialize string 'str' in netstring format. */
size_t netstr_tstr_serialized_len_cb(const TCHAR *str)
{
size_t str_len_cch;
if (!str) return 0;
str_len_cch = tstr_len(str);
return netstr_tstrn_serialized_len_cb(str_len_cch);
}
/* Return number of bytes needed to serialize integer 'num' in netstring format. */
size_t netstr_int_serialized_len_cb(int num)
{
size_t str_len_cch;
size_t total_len_cch;
str_len_cch = digits_for_number(num);
total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2;
return total_len_cch * sizeof(TCHAR);
}
int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
{
char * buf;
size_t buf_len_cb;
size_t len_needed_cb;
TCHAR * num_str;
size_t str_len_cch;
size_t len_cb;
size_t total_len_cb = 0;
assert(buf_len_cb_ptr);
if (!buf_len_cb_ptr)
return FALSE;
if (!buf_ptr)
{
*buf_len_cb_ptr += netstr_tstr_serialized_len_cb(str);
return TRUE;
}
buf = (char*)*buf_ptr;
assert(buf);
if (!buf)
return FALSE;
buf_len_cb = *buf_len_cb_ptr;
assert(buf_len_cb > 0);
if (buf_len_cb <= 0)
return FALSE;
len_needed_cb = netstr_tstr_serialized_len_cb(str);
if (len_needed_cb > buf_len_cb)
return FALSE;
str_len_cch = tstr_len(str);
num_str = tstr_printf(_T("%d:"), str_len_cch);
if (!num_str)
return FALSE;
len_cb = tstr_len(num_str)*sizeof(TCHAR);
memcpy(buf, num_str, len_cb);
buf += len_cb;
total_len_cb += len_cb;
assert(total_len_cb <= len_needed_cb);
len_cb = tstr_len(str)*sizeof(TCHAR);
memcpy(buf, str, len_cb);
buf += len_cb;
total_len_cb += len_cb;
assert(total_len_cb <= len_needed_cb);
len_cb = sizeof(TCHAR);
memcpy(buf, _T(","), len_cb);
buf += len_cb;
total_len_cb += len_cb;
assert(total_len_cb == len_needed_cb);
*buf_len_cb_ptr -= total_len_cb;
*buf_ptr = (TCHAR*)buf;
free((void*)num_str);
return TRUE;
}
int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
{
TCHAR * num_str;
int f_ok;
assert(buf_len_cb_ptr);
if (!buf_len_cb_ptr)
return FALSE;
if (!buf_ptr)
{
*buf_len_cb_ptr += netstr_int_serialized_len_cb(num);
return TRUE;
}
num_str = tstr_printf(_T("%d"), num);
if (!num_str)
return FALSE;
f_ok = netstr_tstr_serialize(num_str, buf_ptr, buf_len_cb_ptr);
free((void*)num_str);
return f_ok;
}
/* Parse a netstring number i.e. a list of digits until ':', skipping ':'.
Returns FALSE if there's an error parsing (string doesn't follow the format) */
static int netstr_get_str_len(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *num_out)
{
int num = 0;
const TCHAR * tmp;
size_t str_len_cb;
TCHAR c;
int digit = 0;
assert(str_ptr);
if (!str_ptr)
return FALSE;
assert(str_len_cb_ptr);
if (!str_len_cb_ptr)
return FALSE;
assert(num_out);
if (!num_out)
return FALSE;
tmp = *str_ptr;
assert(tmp);
if (!tmp)
return FALSE;
str_len_cb = *str_len_cb_ptr;
assert(str_len_cb > 0);
if (str_len_cb <= 0)
return FALSE;
for (;;) {
str_len_cb -= sizeof(TCHAR);
if (str_len_cb < 0)
return FALSE;
c = *tmp++;
if (_T(':') == c)
break;
if ( (c >= _T('0')) && (c <= _T('9')) )
digit = (int)c - _T('0');
else
return FALSE;
num = (num * 10) + digit;
}
if (str_len_cb == *str_len_cb_ptr)
return FALSE;
*str_ptr = tmp;
*str_len_cb_ptr = str_len_cb;
*num_out = num;
return TRUE;
}
int netstr_valid_separator(TCHAR c)
{
if (c == _T(','))
return TRUE;
return FALSE;
}
int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out)
{
int f_ok;
size_t str_len_cch;
size_t str_len_cb;
const TCHAR * str;
const TCHAR * str_copy;
int num;
f_ok = netstr_get_str_len(str_ptr, str_len_cb_ptr, &num);
if (!f_ok)
return FALSE;
assert(num >= 0);
str_len_cch = (size_t)num;
str_len_cb = (str_len_cch+1)*sizeof(TCHAR);
if (str_len_cb > *str_len_cb_ptr)
return FALSE;
str = *str_ptr;
if (!netstr_valid_separator(str[str_len_cch]))
return FALSE;
str_copy = (const TCHAR*)tstr_dupn(str, str_len_cch);
if (!str_copy)
return FALSE;
*str_out = str_copy;
*str_len_cch_out = str_len_cch;
*str_ptr = str + str_len_cch + 1;
*str_len_cb_ptr -= str_len_cb ;
return TRUE;
}
int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out)
{
const TCHAR * str = NULL;
const TCHAR * tmp;
TCHAR c;
size_t str_len_cch;
int f_ok;
int num = 0;
int digit = 0;
f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &str, &str_len_cch);
if (!f_ok)
return FALSE;
tmp = str;
while (*tmp) {
c = *tmp++;
if ( (c >= _T('0')) && (c <= _T('9')) )
digit = (int)c - _T('0');
else
goto Error;
num = (num * 10) + digit;
}
*int_out = num;
free((void*)str);
return TRUE;
Error:
free((void*)str);
return FALSE;
}

View file

@ -1,28 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef NETSTR_H__
#define NETSTR_H__
#ifdef __cplusplus
extern "C"
{
#endif
#define NETSTR_SEP_TC _T(':')
#define NETSTR_END_TC _T(',')
size_t digits_for_number(int num);
size_t netstr_int_serialized_len_cb(int num);
size_t netstr_tstr_serialized_len_cb(const TCHAR *str);
size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch);
int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr);
int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr);
int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out);
int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,26 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "netstr.h"
void netstr_ut(void)
{
assert(1 == digits_for_number(0));
assert(1 == digits_for_number(9));
assert(2 == digits_for_number(10));
assert(2 == digits_for_number(19));
assert(2 == digits_for_number(25));
assert(3 == digits_for_number(125));
assert(4 == digits_for_number(3892));
assert(5 == digits_for_number(38392));
assert(6 == digits_for_number(889931));
assert(7 == digits_for_number(7812345));
assert(1 == digits_for_number(-0));
assert(2 == digits_for_number(-9));
assert(3 == digits_for_number(-10));
assert(4 == digits_for_number(-125));
assert(5 == digits_for_number(-3892));
assert(6 == digits_for_number(-38392));
assert(7 == digits_for_number(-889931));
assert(8 == digits_for_number(-7812345));
}

View file

@ -1,387 +0,0 @@
/*
Copyright (C) 2006 Yangli Hector Yee
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program;
if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Code from http://pdiff.svn.sourceforge.net
*/
#include "pdiff.h"
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI 3.14159265f
#endif
CompareArgs::CompareArgs()
{
ImgA = NULL;
ImgB = NULL;
ImgDiff = NULL;
FieldOfView = 45.0f;
Gamma = 2.2f;
Luminance = 100.0f;
}
CompareArgs::~CompareArgs()
{
if (ImgA) delete ImgA;
if (ImgB) delete ImgB;
if (ImgDiff) delete ImgDiff;
}
#define MAX_PYR_LEVELS 8
class LPyramid
{
public:
LPyramid(float *image, int width, int height);
virtual ~LPyramid();
float Get_Value(int x, int y, int level);
protected:
float *Copy(float *img);
void Convolve(float *a, float *b);
// Succesively blurred versions of the original image
float *Levels[MAX_PYR_LEVELS];
int Width;
int Height;
};
LPyramid::LPyramid(float *image, int width, int height) :
Width(width),
Height(height)
{
// Make the Laplacian pyramid by successively
// copying the earlier levels and blurring them
for (int i=0; i<MAX_PYR_LEVELS; i++) {
if (i == 0) {
Levels[i] = Copy(image);
} else {
Levels[i] = new float[Width * Height];
Convolve(Levels[i], Levels[i - 1]);
}
}
}
LPyramid::~LPyramid()
{
for (int i=0; i<MAX_PYR_LEVELS; i++) {
if (Levels[i]) delete Levels[i];
}
}
float *LPyramid::Copy(float *img)
{
int max = Width * Height;
float *out = new float[max];
for (int i = 0; i < max; i++) out[i] = img[i];
return out;
}
void LPyramid::Convolve(float *a, float *b)
// convolves image b with the filter kernel and stores it in a
{
int y,x,i,j,nx,ny;
const float Kernel[] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
for (y=0; y<Height; y++) {
for (x=0; x<Width; x++) {
int index = y * Width + x;
a[index] = 0.0f;
for (i=-2; i<=2; i++) {
for (j=-2; j<=2; j++) {
nx=x+i;
ny=y+j;
if (nx<0) nx=-nx;
if (ny<0) ny=-ny;
if (nx>=Width) nx=2*(Width-1)-nx;
if (ny>=Height) ny=2*(Height-1)-ny;
a[index] += Kernel[i+2] * Kernel[j+2] * b[ny * Width + nx];
}
}
}
}
}
float LPyramid::Get_Value(int x, int y, int level)
{
int index = x + y * Width;
int l = level;
if (l > MAX_PYR_LEVELS) l = MAX_PYR_LEVELS;
return Levels[level][index];
}
/*
* Given the adaptation luminance, this function returns the
* threshold of visibility in cd per m^2
* TVI means Threshold vs Intensity function
* This version comes from Ward Larson Siggraph 1997
*/
float tvi(float adaptation_luminance)
{
// returns the threshold luminance given the adaptation luminance
// units are candelas per meter squared
float log_a, r, result;
log_a = log10f(adaptation_luminance);
if (log_a < -3.94f) {
r = -2.86f;
} else if (log_a < -1.44f) {
r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f;
} else if (log_a < -0.0184f) {
r = log_a - 0.395f;
} else if (log_a < 1.9f) {
r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f;
} else {
r = log_a - 1.255f;
}
result = powf(10.0f , r);
return result;
}
// computes the contrast sensitivity function (Barten SPIE 1989)
// given the cycles per degree (cpd) and luminance (lum)
float csf(float cpd, float lum)
{
float a, b, result;
a = 440.0f * powf((1.0f + 0.7f / lum), -0.2f);
b = 0.3f * powf((1.0f + 100.0f / lum), 0.15f);
result = a * cpd * expf(-b * cpd) * sqrtf(1.0f + 0.06f * expf(b * cpd));
return result;
}
/*
* Visual Masking Function
* from Daly 1993
*/
float mask(float contrast)
{
float a, b, result;
a = powf(392.498f * contrast, 0.7f);
b = powf(0.0153f * a, 4.0f);
result = powf(1.0f + b, 0.25f);
return result;
}
// convert Adobe RGB (1998) with reference white D65 to XYZ
void AdobeRGBToXYZ(float r, float g, float b, float &x, float &y, float &z)
{
// matrix is from http://www.brucelindbloom.com/
x = r * 0.576700f + g * 0.185556f + b * 0.188212f;
y = r * 0.297361f + g * 0.627355f + b * 0.0752847f;
z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f;
}
void XYZToLAB(float x, float y, float z, float &L, float &A, float &B)
{
static float xw = -1;
static float yw;
static float zw;
// reference white
if (xw < 0) {
AdobeRGBToXYZ(1, 1, 1, xw, yw, zw);
}
const float epsilon = 216.0f / 24389.0f;
const float kappa = 24389.0f / 27.0f;
float f[3];
float r[3];
r[0] = x / xw;
r[1] = y / yw;
r[2] = z / zw;
for (int i = 0; i < 3; i++) {
if (r[i] > epsilon) {
f[i] = powf(r[i], 1.0f / 3.0f);
} else {
f[i] = (kappa * r[i] + 16.0f) / 116.0f;
}
}
L = 116.0f * f[1] - 16.0f;
A = 500.0f * (f[0] - f[1]);
B = 200.0f * (f[1] - f[2]);
}
unsigned long Yee_Compare(CompareArgs &args)
{
if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) ||
(args.ImgA->Get_Height() != args.ImgB->Get_Height())) {
return DIFFERENT_SIZES;
}
unsigned int i, dim;
dim = args.ImgA->Get_Width() * args.ImgA->Get_Height();
bool identical = true;
for (i = 0; i < dim; i++) {
if (args.ImgA->Get(i) != args.ImgB->Get(i)) {
identical = false;
break;
}
}
if (identical) {
return IDENTICAL;
}
// assuming colorspaces are in Adobe RGB (1998) convert to XYZ
float *aX = new float[dim];
float *aY = new float[dim];
float *aZ = new float[dim];
float *bX = new float[dim];
float *bY = new float[dim];
float *bZ = new float[dim];
float *aLum = new float[dim];
float *bLum = new float[dim];
float *aA = new float[dim];
float *bA = new float[dim];
float *aB = new float[dim];
float *bB = new float[dim];
unsigned int x, y, w, h;
w = args.ImgA->Get_Width();
h = args.ImgA->Get_Height();
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
float r, g, b, l;
i = x + y * w;
r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma);
g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma);
b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma);
AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]);
XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]);
r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma);
g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma);
b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma);
AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]);
XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]);
aLum[i] = aY[i] * args.Luminance;
bLum[i] = bY[i] * args.Luminance;
}
}
LPyramid *la = new LPyramid(aLum, w, h);
LPyramid *lb = new LPyramid(bLum, w, h);
float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI);
float pixels_per_degree = w / num_one_degree_pixels;
float num_pixels = 1;
unsigned int adaptation_level = 0;
for (i = 0; i < MAX_PYR_LEVELS; i++) {
adaptation_level = i;
if (num_pixels > num_one_degree_pixels) break;
num_pixels *= 2;
}
float cpd[MAX_PYR_LEVELS];
cpd[0] = 0.5f * pixels_per_degree;
for (i = 1; i < MAX_PYR_LEVELS; i++) cpd[i] = 0.5f * cpd[i - 1];
float csf_max = csf(3.248f, 100.0f);
float F_freq[MAX_PYR_LEVELS - 2];
for (i = 0; i < MAX_PYR_LEVELS - 2; i++) F_freq[i] = csf_max / csf( cpd[i], 100.0f);
unsigned int pixels_failed = 0;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
int index = x + y * w;
float contrast[MAX_PYR_LEVELS - 2];
float sum_contrast = 0;
for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
float n1 = fabsf(la->Get_Value(x,y,i) - la->Get_Value(x,y,i + 1));
float n2 = fabsf(lb->Get_Value(x,y,i) - lb->Get_Value(x,y,i + 1));
float numerator = (n1 > n2) ? n1 : n2;
float d1 = fabsf(la->Get_Value(x,y,i+2));
float d2 = fabsf(lb->Get_Value(x,y,i+2));
float denominator = (d1 > d2) ? d1 : d2;
if (denominator < 1e-5f) denominator = 1e-5f;
contrast[i] = numerator / denominator;
sum_contrast += contrast[i];
}
if (sum_contrast < 1e-5) sum_contrast = 1e-5f;
float F_mask[MAX_PYR_LEVELS - 2];
float adapt = la->Get_Value(x,y,adaptation_level) + lb->Get_Value(x,y,adaptation_level);
adapt *= 0.5f;
if (adapt < 1e-5) adapt = 1e-5f;
for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
F_mask[i] = mask(contrast[i] * csf(cpd[i], adapt));
}
float factor = 0;
for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast;
}
if (factor < 1) factor = 1;
if (factor > 10) factor = 10;
float delta = fabsf(la->Get_Value(x,y,0) - lb->Get_Value(x,y,0));
bool pass = true;
// pure luminance test
if (delta > factor * tvi(adapt)) {
pass = false;
} else {
// CIE delta E test with modifications
float color_scale = 1.0f;
// ramp down the color test in scotopic regions
if (adapt < 10.0f) {
color_scale = 1.0f - (10.0f - color_scale) / 10.0f;
color_scale = color_scale * color_scale;
}
float da = aA[index] - bA[index];
float db = aB[index] - bB[index];
da = da * da;
db = db * db;
float delta_e = (da + db) * color_scale;
if (delta_e > factor) {
pass = false;
}
}
if (!pass) {
pixels_failed++;
if (args.ImgDiff) {
args.ImgDiff->Set(255, 0, 0, 255, index);
}
} else {
if (args.ImgDiff) {
args.ImgDiff->Set(0, 0, 0, 255, index);
}
}
}
}
if (aX) delete[] aX;
if (aY) delete[] aY;
if (aZ) delete[] aZ;
if (bX) delete[] bX;
if (bY) delete[] bY;
if (bZ) delete[] bZ;
if (aLum) delete[] aLum;
if (bLum) delete[] bLum;
if (la) delete la;
if (lb) delete lb;
if (aA) delete aA;
if (bA) delete bA;
if (aB) delete aB;
if (bB) delete bB;
return (unsigned long)pixels_failed;
}

View file

@ -1,81 +0,0 @@
#ifndef PDIFF_H_
#define PDIFF_H_
/*
Copyright (C) 2006 Yangli Hector Yee
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program;
if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Code from http://pdiff.sourceforge.net
*/
class RGBAImage
{
public:
virtual int Get_Width(void) const = 0;
virtual int Get_Height(void) const = 0;
virtual unsigned char Get_Red(unsigned int i) = 0;
virtual unsigned char Get_Green(unsigned int i) = 0;
virtual unsigned char Get_Blue(unsigned int i) = 0;
virtual unsigned char Get_Alpha(unsigned int i) = 0;
virtual void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) = 0;
virtual unsigned int Get(int i) const = 0;
};
class RGBAImageData : RGBAImage
{
public:
RGBAImageData(int w, int h)
{
Width = w;
Height = h;
Data = new unsigned int[w * h];
};
~RGBAImageData() { if (Data) delete[] Data; }
unsigned char Get_Red(unsigned int i) { return (Data[i] & 0xFF); }
unsigned char Get_Green(unsigned int i) { return ((Data[i]>>8) & 0xFF); }
unsigned char Get_Blue(unsigned int i) { return ((Data[i]>>16) & 0xFF); }
unsigned char Get_Alpha(unsigned int i) { return ((Data[i]>>24) & 0xFF); }
void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i)
{ Data[i] = r | (g << 8) | (b << 16) | (a << 24); }
int Get_Width(void) const { return Width; }
int Get_Height(void) const { return Height; }
void Set(int x, int y, unsigned int d) { Data[x + y * Width] = d; }
unsigned int Get(int x, int y) const { return Data[x + y * Width]; }
unsigned int Get(int i) const { return Data[i]; }
protected:
int Width;
int Height;
unsigned int * Data;
};
class CompareArgs {
public:
CompareArgs();
~CompareArgs();
RGBAImage *ImgA;
RGBAImage *ImgB;
RGBAImage *ImgDiff;
float FieldOfView; // Field of view in degrees
float Gamma; // The gamma to convert to linear color space
float Luminance; // the display's luminance
};
#define DIFFERENT_SIZES (unsigned long)-1
#define IDENTICAL (unsigned long)0
unsigned long Yee_Compare(CompareArgs &args);
#endif

View file

@ -1,256 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "tstr_util.h"
#include "prefs_util.h"
#include "netstr.h"
/* length of PT_*_PREFIX string in characters. All should have the same length */
#define TYPE_PREFIX_CCH_LEN 2
/* when we serialize names of variables, we prepend name with the following
type indentifiers */
#define PT_INT_PREFIX _T("i ")
#define PT_STRING_PREFIX _T("s ")
static int pref_type_valid(pref_type type)
{
if (PT_INT == type)
return TRUE;
if (PT_STRING == type)
return TRUE;
return FALSE;
}
/* Given a string value 'txt' and it's type 'type', return a string that
encodes type within a string */
TCHAR *pref_tstr_with_type(const TCHAR *txt, pref_type type)
{
if (PT_INT == type)
return tstr_cat(PT_INT_PREFIX, txt);
else if (PT_STRING == type)
return tstr_cat(PT_STRING_PREFIX, txt);
else
assert(0);
return NULL;
}
/* Serialize 'pref' to a buffer 'buf_ptr' of size 'buf_len_cb_ptr'.
Return TRUE if ok, FALSE if failed (e.g. buffer is not large enough).
If 'buf_ptr' is NULL, returns desired size in 'buf_len_cb_ptr'.
*/
static int prefs_serialize_pref(prefs_data *pref, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
{
size_t len_cb;
TCHAR * name_with_type;
int f_ok;
assert(pref);
assert(pref->name);
assert(pref_type_valid(pref->type));
assert(buf_len_cb_ptr);
if (!buf_ptr) {
len_cb = netstr_tstrn_serialized_len_cb(TYPE_PREFIX_CCH_LEN + tstr_len(pref->name));
if (PT_INT == pref->type)
len_cb += netstr_int_serialized_len_cb(*pref->data.data_int);
else if (PT_STRING == pref->type)
len_cb += netstr_tstr_serialized_len_cb(*pref->data.data_str);
else
assert(0);
*buf_len_cb_ptr = len_cb;
return TRUE;
}
name_with_type = pref_tstr_with_type(pref->name, pref->type);
if (!name_with_type) return FALSE;
f_ok = netstr_tstr_serialize(name_with_type, buf_ptr, buf_len_cb_ptr);
free((void*)name_with_type);
if (!f_ok)
return FALSE;
if (PT_INT == pref->type)
f_ok = netstr_int_serialize(*pref->data.data_int, buf_ptr, buf_len_cb_ptr);
else if (PT_STRING == pref->type)
f_ok = netstr_tstr_serialize(*pref->data.data_str, buf_ptr, buf_len_cb_ptr);
else
assert(0);
if (!f_ok)
return FALSE;
return TRUE;
}
/* Return the size of memory required to serialize 'pref' data */
static size_t prefs_serialized_pref_cb_len(prefs_data *pref)
{
int f_ok;
size_t len;
f_ok = prefs_serialize_pref(pref, NULL, &len);
if (!f_ok)
return 0;
return len;
}
/* Serialize 'prefs' as string. Returns newly allocated string and
length, in bytes, of string in '*tstr_len_cb_ptr' (not including
terminating zero). 'tstr_len_cb_ptr' can be NULL.
Returns NULL on error.
Caller needs to free() the result */
TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr)
{
int i = 0;
size_t total_serialized_len_cb = 0;
size_t len_cb;
int f_ok;
TCHAR * serialized = NULL;
TCHAR * tmp;
size_t tmp_len_cb;
/* calculate the size of buffer required to serialize 'prefs' */
while (prefs[i].name) {
len_cb = prefs_serialized_pref_cb_len(&(prefs[i]));
assert(len_cb > 0);
total_serialized_len_cb += len_cb;
++i;
}
if (0 == total_serialized_len_cb)
return NULL;
/* allocate the buffer and serialize to it */
serialized = (TCHAR*)malloc(total_serialized_len_cb+sizeof(TCHAR));
if (!serialized) return NULL;
tmp = serialized;
tmp_len_cb = total_serialized_len_cb;
i = 0;
while (prefs[i].name) {
f_ok = prefs_serialize_pref(&(prefs[i]), &tmp, &tmp_len_cb);
assert(f_ok);
assert(tmp_len_cb >= 0);
++i;
}
assert(0 == tmp_len_cb);
*tmp = 0;
if (tstr_len_cb_ptr)
*tstr_len_cb_ptr = total_serialized_len_cb;
return serialized;
}
/* Find a variable with a given 'name' and 'type' in 'prefs' array */
prefs_data *prefs_find_by_name_type(prefs_data *prefs, const TCHAR *name, pref_type type)
{
int i = 0;
while (prefs[i].name) {
if ((prefs[i].type == type) && (tstr_ieq(name, prefs[i].name))) {
return &(prefs[i]);
}
++i;
}
return NULL;
}
/* Incrementally parse one serialized variable in a string '*str_ptr' of
remaining size '*str_len_cb_ptr'.
It reads name, type and value of the variable from the string and
updates 'prefs' slot with this name/type with this value. If slot
with a given name/type doesn't exist, nothing happens.
It updates the '*str_ptr' and '*str_len_cb_ptr' to reflect consuming
the part that contained one variable. The idea is to call it in a
loop until '*str_len_cb_ptr' reaches 0.
Returns FALSE on error. */
static int prefs_parse_item(prefs_data *prefs, const TCHAR **str_ptr, size_t *str_len_cb_ptr)
{
const TCHAR * name_with_type = NULL;
const TCHAR * name;
size_t str_len_cch;
const TCHAR * value_str = NULL;
int value_int;
int f_ok;
pref_type type;
prefs_data * pref;
assert(str_ptr);
if (!str_ptr) return FALSE;
assert(str_len_cb_ptr);
if (!str_len_cb_ptr) return FALSE;
f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &name_with_type, &str_len_cch);
if (!f_ok)
goto Error;
if (tstr_startswithi(name_with_type, PT_INT_PREFIX))
type = PT_INT;
else if (tstr_startswithi(name_with_type, PT_STRING_PREFIX))
type = PT_STRING;
else {
assert(0);
goto Error;
}
/* skip the type prefix */
name = name_with_type + TYPE_PREFIX_CCH_LEN;
pref = prefs_find_by_name_type(prefs, name, type);
if (PT_STRING == type)
f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &value_str, &str_len_cch);
else if (PT_INT == type)
f_ok = netstr_parse_int(str_ptr, str_len_cb_ptr, &value_int);
else {
assert(0);
goto Error;
}
if (!f_ok)
goto Error;
if (!pref) {
/* it's ok to not have a given preference e.g. when changing version some of the
preferences might go away. But we still want to be notified about that during
developement, since it's unlikely thing to happen */
assert(0);
goto Exit;
}
if (PT_INT == type)
*pref->data.data_int = value_int;
else if (PT_STRING == type) {
/* taking memory ownership */
*pref->data.data_str = (TCHAR*)value_str;
value_str = NULL;
} else {
assert(0);
goto Error;
}
Exit:
free((void*)name_with_type);
free((void*)value_str);
return TRUE;
Error:
free((void*)name_with_type);
free((void*)value_str);
return FALSE;
}
int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cch)
{
int f_ok;
size_t str_len_cb;
assert(str);
if (!str) return FALSE;
if (-1 == str_len_cch)
str_len_cch = tstr_len(str);
str_len_cb = str_len_cch * sizeof(TCHAR);
while (0 != str_len_cb) {
f_ok = prefs_parse_item(prefs, &str, &str_len_cb);
if (!f_ok)
return FALSE;
}
assert(0 == str_len_cb);
return TRUE;
}

View file

@ -1,38 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef PREFS_H_
#define PREFS_H_
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum pref_type pref_type;
enum pref_type {
PT_INVALID = 0,
PT_INT,
PT_STRING
};
typedef struct prefs_data prefs_data;
/* describes all preferences in a program */
struct prefs_data {
const TCHAR * name;
pref_type type;
union {
void * data_void;
int * data_int;
TCHAR ** data_str;
} data;
};
TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr);
int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cb);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,22 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef __STR_STRSAFE_H
#define __STR_STRSAFE_H
/* When using MSVC, use <strsafe.h>, emulate it on other compiler (e.g. mingw) */
#ifndef __GNUC__
#include <strsafe.h>
#else
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define STRSAFE_E_INSUFFICIENT_BUFFER -1
#define _vsnprintf_s(p,s,z,f,a) vsnprintf(p,s,f,a)
#define StringCchVPrintfA vsnprintf
#define StringCchPrintfA snprintf
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#endif
#endif

View file

@ -1,970 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
/* The most basic things, including string handling functions */
#include "base_util.h"
#include "str_util.h"
#include "str_strsafe.h"
/* TODO: should probably be based on MSVC version */
#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400)
void strcpy_s(char *dst, size_t dstLen, const char *src)
{
size_t toCopy;
assert(dst);
assert(src);
assert(dstLen > 0);
if (!dst || !src || dstLen <= 0)
return;
toCopy = strlen(src);
if (toCopy > (dstLen-1))
toCopy = dstLen - 1;
strncpy(dst, src, toCopy);
dst[toCopy] = 0;
}
#endif
void no_op(void)
{
/* This really is a no-op, just to silence the compiler */
}
int char_is_ws_or_zero(char c)
{
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n':
case 0:
return TRUE;
}
return FALSE;
}
int char_is_ws(char c)
{
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n':
return TRUE;
}
return FALSE;
}
int char_is_digit(char c)
{
if ((c >= '0') && (c <= '9'))
return TRUE;
return FALSE;
}
/* Concatenate 4 strings. Any string can be NULL.
Caller needs to free() memory. */
char *str_cat4(const char *str1, const char *str2, const char *str3, const char *str4)
{
char *str;
char *tmp;
size_t str1_len = 0;
size_t str2_len = 0;
size_t str3_len = 0;
size_t str4_len = 0;
if (str1)
str1_len = strlen(str1);
if (str2)
str2_len = strlen(str2);
if (str3)
str3_len = strlen(str3);
if (str4)
str4_len = strlen(str4);
str = (char*)zmalloc(str1_len + str2_len + str3_len + str4_len + 1);
if (!str)
return NULL;
tmp = str;
if (str1) {
memcpy(tmp, str1, str1_len);
tmp += str1_len;
}
if (str2) {
memcpy(tmp, str2, str2_len);
tmp += str2_len;
}
if (str3) {
memcpy(tmp, str3, str3_len);
tmp += str3_len;
}
if (str4) {
memcpy(tmp, str4, str1_len);
}
return str;
}
/* Concatenate 3 strings. Any string can be NULL.
Caller needs to free() memory. */
char *str_cat3(const char *str1, const char *str2, const char *str3)
{
return str_cat4(str1, str2, str3, NULL);
}
/* Concatenate 2 strings. Any string can be NULL.
Caller needs to free() memory. */
char *str_cat(const char *str1, const char *str2)
{
return str_cat4(str1, str2, NULL, NULL);
}
char *str_dup(const char *str)
{
return str_cat4(str, NULL, NULL, NULL);
}
char *str_dupn(const char *str, size_t str_len_cch)
{
char *copy;
if (!str)
return NULL;
copy = (char*)malloc(str_len_cch+1);
if (!copy)
return NULL;
memcpy(copy, str, str_len_cch);
copy[str_len_cch] = 0;
return copy;
}
int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size)
{
char *end = dst + dst_cch_size - 1;
if (0 == dst_cch_size) {
if (0 == src_cch_size)
return TRUE;
else
return FALSE;
}
while ((dst < end) && (src_cch_size > 0)) {
*dst++ = *src++;
--src_cch_size;
}
*dst = 0;
if (0 == src_cch_size)
return TRUE;
else
return FALSE;
}
int str_copy(char *dst, size_t dst_cch_size, const char *src)
{
char *end = dst + dst_cch_size - 1;
if (0 == dst_cch_size)
return FALSE;
while ((dst < end) && *src) {
*dst++ = *src++;
}
*dst = 0;
if (0 == *src)
return TRUE;
else
return FALSE;
}
int str_eq(const char *str1, const char *str2)
{
if (!str1 && !str2)
return TRUE;
if (!str1 || !str2)
return FALSE;
if (0 == strcmp(str1, str2))
return TRUE;
return FALSE;
}
int str_ieq(const char *str1, const char *str2)
{
if (!str1 && !str2)
return TRUE;
if (!str1 || !str2)
return FALSE;
if (0 == _stricmp(str1, str2))
return TRUE;
return FALSE;
}
int str_eqn(const char *str1, const char *str2, int len)
{
if (!str1 && !str2)
return TRUE;
if (!str1 || !str2)
return FALSE;
if (0 == strncmp(str1, str2, len))
return TRUE;
return FALSE;
}
/* return true if 'str' starts with 'txt', case-sensitive */
int str_startswith(const char *str, const char *txt)
{
if (!str && !txt)
return TRUE;
if (!str || !txt)
return FALSE;
if (0 == strncmp(str, txt, strlen(txt)))
return TRUE;
return FALSE;
}
/* return true if 'str' starts with 'txt', NOT case-sensitive */
int str_startswithi(const char *str, const char *txt)
{
if (!str && !txt)
return TRUE;
if (!str || !txt)
return FALSE;
if (0 == _strnicmp(str, txt, strlen(txt)))
return TRUE;
return FALSE;
}
int str_endswith(const char *txt, const char *end)
{
size_t end_len;
size_t txt_len;
if (!txt || !end)
return FALSE;
txt_len = strlen(txt);
end_len = strlen(end);
if (end_len > txt_len)
return FALSE;
if (str_eq(txt+txt_len-end_len, end))
return TRUE;
return FALSE;
}
int str_endswithi(const char *txt, const char *end)
{
size_t end_len;
size_t txt_len;
if (!txt || !end)
return FALSE;
txt_len = strlen(txt);
end_len = strlen(end);
if (end_len > txt_len)
return FALSE;
if (str_ieq(txt+txt_len-end_len, end))
return TRUE;
return FALSE;
}
int str_endswith_char(const char *str, char c)
{
char end[2];
end[0] = c;
end[1] = 0;
return str_endswith(str, end);
}
int str_empty(const char *str)
{
if (!str)
return TRUE;
if (0 == *str)
return TRUE;
return FALSE;
}
/* Find character 'c' in string 'txt'.
Return pointer to this character or NULL if not found */
const char *str_find_char(const char *txt, char c)
{
while (*txt != c) {
if (0 == *txt)
return NULL;
++txt;
}
return txt;
}
/* split a string '*txt' at the border character 'c'. Something like python's
string.split() except called iteratively.
Returns a copy of the string (must be free()d by the caller).
Returns NULL to indicate there's no more items. */
char *str_split_iter(char **txt, char c)
{
const char *tmp;
const char *pos;
char *result;
tmp = (const char*)*txt;
if (!tmp)
return NULL;
pos = str_find_char(tmp, c);
if (pos) {
result = str_dupn(tmp, (int)(pos-tmp));
*txt = (char*)pos+1;
} else {
result = str_dup(tmp);
*txt = NULL; /* next iteration will return NULL */
}
return result;
}
/* Replace all posible versions (Unix, Windows, Mac) of newline character
with 'replace'. Returns newly allocated string with normalized newlines
or NULL if error.
Caller needs to free() the result */
char *str_normalize_newline(const char *txt, const char *replace)
{
size_t replace_len;
char c;
char * result;
const char * tmp;
char * tmp_out;
size_t result_len = 0;
replace_len = strlen(replace);
tmp = txt;
for (;;) {
c = *tmp++;
if (!c)
break;
if (0xa == c) {
/* a single 0xa => Unix */
result_len += replace_len;
} else if (0xd == c) {
if (0xa == *tmp) {
/* 0xd 0xa => dos */
result_len += replace_len;
++tmp;
}
else {
/* just 0xd => Mac */
result_len += replace_len;
}
} else
++result_len;
}
if (0 == result_len)
return NULL;
result = (char*)malloc(result_len+1);
if (!result)
return NULL;
tmp_out = result;
for (;;) {
c = *txt++;
if (!c)
break;
if (0xa == c) {
/* a single 0xa => Unix */
memcpy(tmp_out, replace, replace_len);
tmp_out += replace_len;
} else if (0xd == c) {
if (0xa == *txt) {
/* 0xd 0xa => dos */
memcpy(tmp_out, replace, replace_len);
tmp_out += replace_len;
++txt;
}
else {
/* just 0xd => Mac */
memcpy(tmp_out, replace, replace_len);
tmp_out += replace_len;
}
} else
*tmp_out++ = c;
}
*tmp_out = 0;
return result;
}
#define WHITE_SPACE_CHARS " \n\t\r"
/* Strip all 'to_strip' characters from the beginning of the string.
Does stripping in-place */
void str_strip_left(char *txt, const char *to_strip)
{
char *new_start = txt;
char c;
if (!txt || !to_strip)
return;
for (;;) {
c = *new_start;
if (0 == c)
break;
if (!str_contains(to_strip, c))
break;
++new_start;
}
if (new_start != txt) {
memmove(txt, new_start, strlen(new_start)+1);
}
}
/* Strip white-space characters from the beginning of the string.
Does stripping in-place */
void str_strip_ws_left(char *txt)
{
str_strip_left(txt, WHITE_SPACE_CHARS);
}
void str_strip_right(char *txt, const char *to_strip)
{
char * new_end;
char c;
if (!txt || !to_strip)
return;
if (0 == *txt)
return;
/* point at the last character in the string */
new_end = txt + strlen(txt) - 1;
for (;;) {
c = *new_end;
if (!str_contains(to_strip, c))
break;
if (txt == new_end)
break;
--new_end;
}
if (str_contains(to_strip, *new_end))
new_end[0] = 0;
else
new_end[1] = 0;
}
void str_strip_ws_right(char *txt)
{
str_strip_right(txt, WHITE_SPACE_CHARS);
}
void str_strip_both(char *txt, const char *to_strip)
{
str_strip_left(txt, to_strip);
str_strip_right(txt, to_strip);
}
void str_strip_ws_both(char *txt)
{
str_strip_ws_left(txt);
str_strip_ws_right(txt);
}
#if 0
int utf8_eq(const utf8* str1, const utf8* str2)
{
return str_eq(str1, str2);
}
int utf8_eqn(const utf8* str1, const utf8* str2, int len)
{
return str_eqn(str1, str2, len);
}
int utf8_copy(utf8 *dst, int dst_size_bytes, utf8* src)
{
return str_copy(dst, dst_size_bytes, src);
}
utf8 *utf8_dup(const utf8 *str)
{
return str_dup(str);
}
utf8 *utf8_cat4(const utf8 *str1, const utf8 *str2, const utf8 *str3, const utf8 *str4)
{
return str_cat4(str1, str2, str3, str4);
}
utf8 *utf8_cat3(const utf8 *str1, const utf8 *str2, const utf8 *str3)
{
return str_cat4(str1, str2, str3, NULL);
}
utf8 *utf8_cat(const utf8 *str1, const utf8 *str2)
{
return str_cat4(str1, str2, NULL, NULL);
}
int utf8_endswith(const utf8 *str, const utf8 *end)
{
return str_endswith(str, end);
}
#endif
#define HEX_NUMBERS "0123456789ABCDEF"
static void char_to_hex(unsigned char c, char* buffer)
{
buffer[0] = HEX_NUMBERS[c / 16];
buffer[1] = HEX_NUMBERS[c % 16];
}
int str_contains(const char *str, char c)
{
const char *pos = str_find_char(str, c);
if (!pos)
return FALSE;
return TRUE;
}
#define CHAR_URL_DONT_ENCODE "-_.!~*'()"
int char_needs_url_encode(char c)
{
if ((c >= 'a') && (c <= 'z'))
return FALSE;
if ((c >= 'A') && (c <= 'Z'))
return FALSE;
if ((c >= '0') && (c <= '9'))
return FALSE;
if (str_contains(CHAR_URL_DONT_ENCODE, c))
return FALSE;
return TRUE;
}
/* url-encode 'str'. Returns NULL in case of error. Caller needs to free()
the result */
char *str_url_encode(const char *str)
{
char * encoded;
char * result;
int res_len = 0;
const char * tmp = str;
/* calc the size of the string after url encoding */
while (*tmp) {
if (char_needs_url_encode(*tmp))
res_len += 3;
else
++res_len;
tmp++;
}
if (0 == res_len)
return NULL;
encoded = (char*)malloc(res_len+1);
if (!encoded)
return NULL;
result = encoded;
tmp = str;
while (*tmp) {
if (char_needs_url_encode(*tmp)) {
*encoded++ = '%';
char_to_hex(*tmp, encoded);
encoded += 2;
} else {
if (' ' == *tmp)
*encoded++ = '+';
else
*encoded++ = *tmp;
}
tmp++;
}
*encoded = 0;
return result;
}
char *str_escape(const char *txt)
{
/* TODO: */
return str_dup(txt);
}
char *str_printf(const char *format, ...)
{
char *result;
va_list args;
va_start(args, format);
result = str_printf_args(format, args);
va_end(args);
return result;
}
char *str_printf_args(const char *format, va_list args)
{
#ifdef _WIN32
HRESULT hr;
char message[256];
char * buf;
size_t bufCchSize;
char * result = NULL;
buf = &(message[0]);
bufCchSize = sizeof(message);
for (;;)
{
/* TODO: this only works on windows with recent C library */
hr = StringCchVPrintfA(buf, bufCchSize, format, args);
if (S_OK == hr)
break;
if (STRSAFE_E_INSUFFICIENT_BUFFER != hr)
{
/* any error other than buffer not big enough:
a) should not happen
b) means we give up */
assert(FALSE);
goto Error;
}
/* we have to make the buffer bigger. The algorithm used to calculate
the new size is arbitrary (aka. educated guess) */
if (buf != &(message[0]))
free(buf);
if (bufCchSize < 4*1024)
bufCchSize += bufCchSize;
else
bufCchSize += 1024;
buf = (char *)malloc(bufCchSize*sizeof(char));
if (NULL == buf)
goto Error;
}
/* free the buffer if it was dynamically allocated */
if (buf == &(message[0]))
return str_dup(buf);
return buf;
Error:
if (buf != &(message[0]))
free((void*)buf);
return NULL;
#else
char* buf;
int len = vasprintf(&buf, format, args);
return buf;
#endif
}
#ifdef _WIN32
void win32_dbg_out(const char *format, ...)
{
char buf[4096];
char * p = buf;
int written;
va_list args;
va_start(args, format);
written = _vsnprintf(p,sizeof(buf), format, args);
/* printf(buf);
fflush(stdout); */
OutputDebugStringA(buf);
va_end(args);
}
void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen)
{
unsigned char buf[64+1];
unsigned char * curPos;
int bufCharsLeft;
if (dsc) win32_dbg_out(dsc); /* a bit dangerous if contains formatting codes */
if (!data) return;
bufCharsLeft = sizeof(buf)-1;
curPos = buf;
while (dataLen > 0) {
if (bufCharsLeft <= 1) {
*curPos = 0;
win32_dbg_out((char*)buf);
bufCharsLeft = sizeof(buf)-1;
curPos = buf;
}
char_to_hex(*data, curPos);
curPos += 2;
bufCharsLeft -= 2;
--dataLen;
++data;
}
if (curPos != buf) {
*curPos = 0;
win32_dbg_out(buf);
}
win32_dbg_out("\n");
}
#endif
/* Given a pointer to a string in '*txt', skip past whitespace in the string
and put the result in '*txt' */
void str_skip_ws(char **txtInOut)
{
char *cur;
if (!txtInOut)
return;
cur = *txtInOut;
if (!cur)
return;
while (char_is_ws(*cur)) {
++cur;
}
*txtInOut = cur;
}
char *str_parse_quoted(char **txt)
{
char * strStart;
char * strCopy;
char * cur;
char * dst;
char c;
size_t len;
assert(txt);
if (!txt) return NULL;
strStart = *txt;
assert(strStart);
if (!strStart) return NULL;
assert('"' == *strStart);
/* TODO: rewrite as 2-phase logic so that counting and copying are always in sync */
++strStart;
cur = strStart;
len = 0;
for (;;) {
c = *cur;
if ((0 == c) || ('"' == c))
break;
if ('\\' == c) {
/* TODO: should I un-escape more than '"' ?
I used to un-escape '\' as well, but it wasn't right and
files with UNC path like "\\foo\file.pdf" failed to load */
if ('"' == cur[1]) {
++cur;
c = *cur;
}
}
++cur;
++len;
}
strCopy = (char*)malloc(len+1);
if (!strCopy)
return NULL;
cur = strStart;
dst = strCopy;
for (;;) {
c = *cur;
if (0 == c)
break;
if ('"' == c) {
++cur;
break;
}
if ('\\' == c) {
/* TODO: should I un-escape more than '"' ?
I used to un-escape '\' as well, but it wasn't right and
files with UNC path like "\\foo\file.pdf" failed to load */
if ('"' == cur[1]) {
++cur;
c = *cur;
}
}
*dst++ = c;
++cur;
}
*dst = 0;
*txt = cur;
return strCopy;
}
char *str_parse_non_quoted(char **txt)
{
char * cur;
char * strStart;
char * strCopy;
char c;
size_t strLen;
strStart = *txt;
assert(strStart);
if (!strStart) return NULL;
assert('"' != *strStart);
cur = strStart;
for (;;) {
c = *cur;
if (char_is_ws_or_zero(c))
break;
++cur;
}
strLen = cur - strStart;
assert(strLen > 0);
strCopy = str_dupn(strStart, strLen);
*txt = cur;
return strCopy;
}
/* 'txt' is path that can be:
- escaped, in which case it starts with '"', ends with '"' and each '"' that is part of the name is escaped
with '\'
- unescaped, in which case it start with != '"' and ends with ' ' or eol (0)
This function extracts escaped or unescaped path from 'txt'. Returns NULL in case of error.
Caller needs to free() the result. */
char *str_parse_possibly_quoted(char **txt)
{
char * cur;
char * str_copy;
if (!txt)
return NULL;
cur = *txt;
if (!cur)
return NULL;
str_skip_ws(&cur);
if (0 == *cur)
return NULL;
if ('"' == *cur)
str_copy = str_parse_quoted(&cur);
else
str_copy = str_parse_non_quoted(&cur);
*txt = cur;
return str_copy;
}
void str_array_init(str_array *str_arr)
{
assert(str_arr);
if (!str_arr) return;
memzero(str_arr, sizeof(str_array));
}
void str_array_free(str_array *str_arr)
{
int i;
assert(str_arr);
if (!str_arr) return;
for (i = 0; i < str_arr->items_count; i++)
free(str_arr->items[i]);
free(str_arr->items);
str_array_init(str_arr);
}
void str_array_delete(str_array *str_arr)
{
assert(str_arr);
if (!str_arr) return;
str_array_free(str_arr);
free((void*)str_arr);
}
str_item *str_array_get(str_array *str_arr, int index)
{
assert(str_arr);
if (!str_arr) return NULL;
assert(index >= 0);
assert(index < str_arr->items_count);
if ((index < 0) || (index >= str_arr->items_count))
return NULL;
return str_arr->items[index];
}
int str_array_get_count(str_array *str_arr)
{
assert(str_arr);
if (!str_arr) return 0;
return str_arr->items_count;
}
/* Set one string at position 'index' in 'str_arr'. Space for the item
must already be allocated. */
str_item *str_array_set(str_array *str_arr, int index, const char *str)
{
str_item * new_item;
size_t str_len_cch;
assert(str_arr);
if (!str_arr) return NULL;
if (index >= str_arr->items_count)
return NULL;
str_len_cch = str_len(str);
new_item = (str_item*)malloc(sizeof(str_item) + str_len_cch*sizeof(char));
if (!new_item)
return NULL;
str_copy(new_item->str, str_len_cch+1, str);
if (str_arr->items[index])
free(str_arr->items[index]);
str_arr->items[index] = new_item;
return new_item;
}
#define STR_ARR_GROW_VALUE 32
/* make a generic array alloc */
str_item *str_array_add(str_array *str_arr, const char *str)
{
str_item ** tmp;
str_item * new_item;
void * data;
int n;
if (str_arr->items_count >= str_arr->items_allocated) {
/* increase memory for items if necessary */
n = str_arr->items_allocated + STR_ARR_GROW_VALUE;
tmp = (str_item**)realloc(str_arr->items, n * sizeof(str_item *));
if (!tmp)
return NULL;
str_arr->items = tmp;
data = &(str_arr->items[str_arr->items_count]);
memzero(data, STR_ARR_GROW_VALUE * sizeof(str_item *));
str_arr->items_allocated = n;
}
str_arr->items_count++;
new_item = str_array_set(str_arr, str_arr->items_count - 1, str);
if (!new_item)
--str_arr->items_count;
return new_item;
}
int str_array_exists_no_case(str_array *str_arr, const char *str)
{
int count, i;
str_item * item;
char * item_str;
if (!str_arr || !str)
return FALSE;
count = str_arr->items_count;
for (i = 0; i < count; i++)
{
item = str_arr->items[i];
item_str = item->str;
if (str_ieq(str, item_str))
return TRUE;
}
return FALSE;
}
str_item *str_array_add_no_dups(str_array *str_arr, const char *str)
{
if (str_array_exists_no_case(str_arr, str))
return NULL;
return str_array_add(str_arr, str);
}

View file

@ -1,117 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef STR_UTIL_H_
#define STR_UTIL_H_
#ifdef __cplusplus
extern "C"
{
#endif
/* DOS is 0xd 0xa */
#define DOS_NEWLINE "\x0d\x0a"
/* Mac is single 0xd */
#define MAC_NEWLINE "\x0d"
/* Unix is single 0xa (10) */
#define UNIX_NEWLINE "\x0a"
#define UNIX_NEWLINE_C 0xa
#ifdef _WIN32
#define DIR_SEP_CHAR '\\'
#define DIR_SEP_STR "\\"
#else
#define DIR_SEP_CHAR '/'
#define DIR_SEP_STR "/"
#endif
void no_op(void);
#ifdef DEBUG
#ifdef _WIN32
#define DBG_OUT win32_dbg_out
#define DBG_OUT_HEX win32_dbg_out_hex
#else
#define DBG_OUT printf
#define DBG_OUT_HEX(...) no_op()
#endif
#else
#define DBG_OUT(...) no_op()
#define DBG_OUT_HEX(...) no_op()
#endif
int char_is_ws_or_zero(char c);
int char_is_ws(char c);
int char_is_digit(char c);
/* TODO: should probably be based on MSVC version */
#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400)
void strcpy_s(char *dst, size_t dstLen, const char *src);
#endif
#define str_len strlen
int str_eq(const char *str1, const char *str2);
int str_ieq(const char *str1, const char *str2);
#define str_eq_no_case str_ieq
int str_eqn(const char *str1, const char *str2, int len);
int str_startswith(const char *str, const char *txt);
int str_startswithi(const char *str, const char *txt);
int str_endswith(const char *str, const char *end);
int str_endswithi(const char *str, const char *end);
int str_endswith_char(const char *str, char c);
int str_empty(const char *str);
int str_copy(char *dst, size_t dst_cch_size, const char *src);
int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size);
char * str_dup(const char *str);
char * str_dupn(const char *str, size_t len);
char * str_cat(const char *str1, const char *str2);
char * str_cat3(const char *str1, const char *str2, const char *str3);
char * str_cat4(const char *str1, const char *str2, const char *str3, const char *str4);
char * str_url_encode(const char *str);
int char_needs_url_escape(char c);
int str_contains(const char *str, char c);
char * str_printf_args(const char *format, va_list args);
char * str_printf(const char *format, ...);
const char *str_find_char(const char *txt, char c);
char * str_split_iter(char **txt, char c);
char * str_normalize_newline(const char *txt, const char *replace);
void str_strip_left(char *txt, const char *to_strip);
void str_strip_ws_left(char *txt);
void str_strip_right(char *txt, const char *to_strip);
void str_strip_ws_right(char *txt);
void str_strip_both(char *txt, const char *to_strip);
void str_strip_ws_both(char *txt);
char * str_escape(const char *txt);
char * str_parse_possibly_quoted(char **txt);
#ifdef DEBUG
void str_util_test(void);
#endif
typedef struct str_item str_item;
typedef struct str_array str_array;
struct str_item {
void * opaque; /* opaque data that the user can use */
char str[1];
};
struct str_array {
int items_allocated;
int items_count;
str_item ** items;
};
void str_array_init(str_array *str_arr);
void str_array_free(str_array *str_arr);
void str_array_delete(str_array *str_arr);
str_item *str_array_set(str_array *str_arr, int index, const char *str);
str_item *str_array_add(str_array *str_arr, const char *str);
str_item *str_array_get(str_array *str_arr, int index);
int str_array_get_count(str_array *str_arr);
int str_array_exists_no_case(str_array *str_arr, const char *str);
str_item *str_array_add_no_dups(str_array *str_arr, const char *str);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,44 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "str_util.h"
#ifndef DEBUG
#define DEBUG 1
#endif
#define LAST_TXT "last"
void str_util_test(void)
{
char buf[256];
char * tmp;
assert(!str_endswith(NULL, NULL));
assert(!str_endswith(NULL, "foo"));
assert(!str_endswith("bar", NULL));
assert(!str_endswith("bar", "baru"));
assert(str_endswith("whammy", "whammy"));
assert(str_endswith("whammy", "hammy"));
assert(str_endswith("whammy", "y"));
assert(str_endswith("whmmy", ""));
str_copy(buf, sizeof(buf), LAST_TXT);
str_strip_left(buf, "zot");
assert(str_eq(buf, LAST_TXT));
str_strip_right(buf, "zpo");
assert(str_eq(buf, LAST_TXT));
str_copy(buf, sizeof(buf), " \n last ");
str_strip_left(buf, " \n");
assert(str_eq(buf, "last "));
str_strip_right(buf, " \n");
assert(str_eq(buf, LAST_TXT));
str_copy(buf, sizeof(buf), LAST_TXT);
str_strip_left(buf, LAST_TXT);
assert(0 == buf[0]);
str_copy(buf, sizeof(buf), LAST_TXT);
str_strip_right(buf, LAST_TXT);
assert(0 == buf[0]);
str_copy(buf, sizeof(buf), "\x0d\x0a");
tmp = str_normalize_newline(buf, UNIX_NEWLINE);
assert(str_eq(tmp, UNIX_NEWLINE));
free((void*)tmp);
tmp = NULL;
}

View file

@ -1,70 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "strlist_util.h"
#include "str_util.h"
int StrList_Len(StrList **root)
{
int len = 0;
StrList * cur;
assert(root);
if (!root)
return 0;
cur = *root;
while (cur) {
++len;
cur = cur->next;
}
return len;
}
BOOL StrList_InsertAndOwn(StrList **root, char *txt)
{
StrList * el;
assert(root && txt);
if (!root || !txt)
return FALSE;
el = (StrList*)malloc(sizeof(StrList));
if (!el)
return FALSE;
el->str = txt;
el->next = *root;
*root = el;
return TRUE;
}
BOOL StrList_Insert(StrList **root, char *txt)
{
char *txtDup;
assert(root && txt);
if (!root || !txt)
return FALSE;
txtDup = str_dup(txt);
if (!txtDup)
return FALSE;
if (!StrList_InsertAndOwn(root, txtDup)) {
free((void*)txtDup);
return FALSE;
}
return TRUE;
}
void StrList_Destroy(StrList **root)
{
StrList * cur;
StrList * next;
if (!root)
return;
cur = *root;
while (cur) {
next = cur->next;
free((void*)cur->str);
free((void*)cur);
cur = next;
}
*root = NULL;
}

View file

@ -1,28 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef STRLIST_UTIL_H_
#define STRLIST_UTIL_H_
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct StrList {
struct StrList * next;
char * str;
} StrList;
char * StrDupN(char *str, size_t len);
char * StrDup(char *str);
int StrList_Len(StrList **root);
BOOL StrList_InsertAndOwn(StrList **root, char *txt);
BOOL StrList_Insert(StrList **root, char *txt);
void StrList_Destroy(StrList **root);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,30 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "file_util.h"
#define DIR_TO_READ "."
int main(int argc, char **argv)
{
FileList* fileList = FileList_Get(DIR_TO_READ, NULL);
if (!fileList) {
printf("Couldn't read dir %s\n", DIR_TO_READ);
goto Exit;
}
FileInfo* fileInfo = fileList->first;
while (fileInfo) {
if (FileInfo_IsDir(fileInfo)) {
printf("d: %s, %s, %d\n", fileInfo->name, fileInfo->path, (int)fileInfo->size);
} else if (FileInfo_IsFile(fileInfo)) {
printf("f: %s, %s, %d\n", fileInfo->name, fileInfo->path, (int)fileInfo->size);
} else {
printf("Unknown type: %s\n", fileInfo->name);
}
fileInfo = fileInfo->next;
}
Exit:
FileList_Delete(fileList);
return 0;
}

View file

@ -1,3 +0,0 @@
* netstr.c and prefs_util.c shouldn't support TCHAR, just utf8 char*
* add mingw makefile
* add cygwin makefile

View file

@ -1,44 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef TSTR_UTIL_H_
#define TSTR_UTIL_H_
#ifdef _UNICODE
#include "wstr_util.h"
#define tstr_len wcslen
#define tstr_dup wstr_dup
#define tstr_dupn wstr_dupn
#define tstr_cat wstr_cat
#define tstr_cat3 wstr_cat3
#define tstr_cat4 wstr_cat4
#define tstr_copy wstr_copy
#define tstr_copyn wstr_copyn
#define tstr_startswith wstr_startswith
#define tstr_startswithi wstr_startswithi
#define tstr_url_encode wstr_url_encode
#define tchar_needs_url_escape wchar_needs_url_escape
#define tstr_contains wstr_contains
#define tstr_printf wstr_printf
#define tstr_ieq wstr_ieq
#define tstr_empty wstr_empty
#else
#include "str_util.h"
#define tstr_len strlen
#define tstr_dup str_dup
#define tstr_dupn str_dupn
#define tstr_cat str_cat
#define tstr_cat3 str_cat3
#define tstr_cat4 str_cat4
#define tstr_copy str_copy
#define tstr_copyn str_copyn
#define tstr_startswith str_startswith
#define tstr_startswithi str_startswithi
#define tstr_url_encode str_url_encode
#define tchar_needs_url_escape char_needs_url_escape
#define tstr_contains str_contains
#define tstr_printf str_printf
#define tstr_ieq str_ieq
#define tstr_empty str_empty
#endif
#endif

View file

@ -1,13 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "str_util.h"
extern void str_util_test(void); /* in str_util_test.c */
int main(int argc, char **argv)
{
printf("starting unit tests\n");
str_util_test();
printf("finished unit tests\n");
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,219 +0,0 @@
#ifndef __DIB_h__
#define __DIB_h__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CDIB.h : header file
//
// Copyright © Dundas Software Ltd. 1999, All Rights Reserved
// //////////////////////////////////////////////////////////////////////////
// Properties:
// NO Abstract class (does not have any objects)
// NO Derived from CWnd
// NO Is a CWnd.
// NO Two stage creation (constructor & Create())
// NO Has a message map
// NO Needs a resource (template)
// YES Persistent objects (saveable on disk)
// YES Uses exceptions
// //////////////////////////////////////////////////////////////////////////
// Desciption :
// CDIBSectionLite is DIBSection wrapper class for win32 and WinCE platforms.
// This class provides a simple interface to DIBSections including loading,
// saving and displaying DIBsections.
//
// Full palette support is provided for Win32 and CE 2.11 and above.
// Using CDIBSectionLite :
// This class is very simple to use. The bitmap can be set using either SetBitmap()
// (which accepts either a Device dependant or device independant bitmap, or a
// resource ID) or by using Load(), which allows an image to be loaded from disk.
// To display the bitmap simply use Draw or Stretch.
//
// eg.
//
// CDIBsection dibsection;
// dibsection.Load(_T("image.bmp"));
// dibsection.Draw(pDC, CPoint(0,0)); // pDC is of type CDC*
//
// CDIBsection dibsection;
// dibsection.SetBitmap(IDB_BITMAP);
// dibsection.Draw(pDC, CPoint(0,0)); // pDC is of type CDC*
//
// The CDIBsection API includes many methods to extract information about the
// image, as well as palette options for getting and setting the current palette.
//
// Author : Chris Maunder (cmaunder@mail.com)
// Date : 12 April 1999
// Modified : Kenny Goers (kennyg@magenic.com)
// Date : 12 December 2000
// Why : Remove all MFC bloat
// CDIB.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// defines
//#define DIBSECTION_NO_DITHER // Disallow dithering via DrawDib functions
#define DIBSECTION_NO_MEMDC_REUSE // Disallow the reuse of memory DC's
//#define DIBSECTION_NO_PALETTE // Remove palette support
// Only provide palette support for non-CE platforms, or for CE 2.11 and above
#define DIBSECTION_NO_DITHER // DrawDib not supported on CE
#if (_WIN32_WCE < 211)
# define DIBSECTION_NO_PALETTE // No palette support on early CE devices
#endif
#define DS_BITMAP_FILEMARKER ((WORD) ('M' << 8) | 'B') // is always "BM" = 0x4D42
/////////////////////////////////////////////////////////////////////////////
// BITMAPINFO wrapper
struct DIBINFO : public BITMAPINFO
{
RGBQUAD arColors[255]; // Color table info - adds an extra 255 entries to palette
operator LPBITMAPINFO() { return (LPBITMAPINFO) this; }
operator LPBITMAPINFOHEADER() { return &bmiHeader; }
RGBQUAD* ColorTable() { return bmiColors; }
};
/////////////////////////////////////////////////////////////////////////////
// LOGPALETTE wrapper
#ifndef DIBSECTION_NO_PALETTE
struct PALETTEINFO : public LOGPALETTE
{
PALETTEENTRY arPalEntries[255]; // Palette entries
PALETTEINFO()
{
palVersion = (WORD) 0x300;
palNumEntries = 0;
::memset(palPalEntry, 0, 256*sizeof(PALETTEENTRY));
}
operator LPLOGPALETTE() { return (LPLOGPALETTE) this; }
operator LPPALETTEENTRY() { return (LPPALETTEENTRY) (palPalEntry); }
};
#endif // DIBSECTION_NO_PALETTE
/////////////////////////////////////////////////////////////////////////////
// CeDIB object
class CeDIB
{
// Construction
public:
CeDIB();
virtual ~CeDIB();
// static helpers
public:
static int BytesPerLine(int nWidth, int nBitsPerPixel);
static int NumColorEntries(int nBitsPerPixel, int nCompression);
static RGBQUAD ms_StdColors[];
#ifndef DIBSECTION_NO_PALETTE
static BOOL UsesPalette(HDC hDC)
{ return (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE); }
static BOOL CreateHalftonePalette(HPALETTE palette, int nNumColors);
#endif // DIBSECTION_NO_PALETTE
// Attributes
public:
HBITMAP GetSafeHandle() const { return (this)? m_hBitmap : NULL; }
operator HBITMAP() const { return GetSafeHandle(); }
void GetSize(SIZE& size) const { size.cx = GetWidth(); size.cy = GetHeight(); }
int GetHeight() const { return m_DIBinfo.bmiHeader.biHeight; }
int GetWidth() const { return m_DIBinfo.bmiHeader.biWidth; }
int GetPlanes() const { return m_DIBinfo.bmiHeader.biPlanes; }
int GetBitCount() const { return m_DIBinfo.bmiHeader.biBitCount; }
LPVOID GetDIBits() { return m_ppvBits; }
LPBITMAPINFO GetBitmapInfo() { return (BITMAPINFO*) m_DIBinfo; }
DWORD GetImageSize() const { return m_DIBinfo.bmiHeader.biSizeImage; }
LPBITMAPINFOHEADER GetBitmapInfoHeader() { return (BITMAPINFOHEADER*) m_DIBinfo; }
// Operations (Palette)
public:
LPRGBQUAD GetColorTable() { return m_DIBinfo.ColorTable(); }
BOOL SetColorTable(UINT nNumColors, RGBQUAD *pColors);
int GetColorTableSize() { return m_iColorTableSize; }
#ifndef DIBSECTION_NO_PALETTE
HPALETTE GetPalette() { return m_hPal; }
BOOL SetPalette(HPALETTE pPalette);
BOOL SetLogPalette(LOGPALETTE* pLogPalette);
#endif // DIBSECTION_NO_PALETTE
// Operations (Setting the bitmap)
public:
BOOL SetBitmap(UINT nIDResource, HINSTANCE hInst = NULL);
BOOL SetBitmap(LPCTSTR lpszResourceName, HINSTANCE hInst = NULL);
BOOL SetBitmap(HBITMAP hBitmap, HPALETTE hPal = NULL);
BOOL SetBitmap(LPBITMAPINFO lpBitmapInfo, LPVOID lpBits);
BOOL Load(LPCTSTR lpszFileName);
BOOL Save(LPCTSTR lpszFileName);
BOOL Copy(CeDIB& Bitmap);
// Operations (Display)
public:
BOOL Draw(HDC hDC, POINT& ptDest, BOOL bForceBackground = FALSE);
BOOL Stretch(HDC hDC, POINT& ptDest, SIZE& size, BOOL bForceBackground = FALSE);
HDC GetMemoryDC(HDC hDC = NULL, BOOL bSelectPalette = TRUE);
BOOL ReleaseMemoryDC(BOOL bForceRelease = FALSE);
// Overrideables
// Implementation
public:
// Implementation
protected:
#ifndef DIBSECTION_NO_PALETTE
BOOL CreatePalette();
BOOL FillDIBColorTable(UINT nNumColors, RGBQUAD *pRGB);
#endif // DIBSECTION_NO_PALETTE
UINT GetColorTableEntries(HDC hdc, HBITMAP hBitmap);
protected:
HBITMAP m_hBitmap; // Handle to DIBSECTION
DIBINFO m_DIBinfo; // Bitmap header & color table info
VOID *m_ppvBits; // Pointer to bitmap bits
UINT m_iColorDataType; // color data type (palette or RGB values)
UINT m_iColorTableSize; // Size of color table
HDC m_hMemDC; // Memory DC for drawing on bitmap
#ifndef DIBSECTION_NO_MEMDC_REUSE
BOOL m_bReuseMemDC; // Reeuse the memory DC? (Quicker, but not fully tested)
#endif
#ifndef DIBSECTION_NO_PALETTE
HPALETTE m_hPal; // Color palette
HPALETTE m_hOldPal;
#endif // DIBSECTION_NO_PALETTE
private:
HBITMAP m_hOldBitmap; // Storage for previous bitmap in Memory DC
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CeDIB_H__35D9F3D4_B960_11D2_A981_2C4476000000__INCLUDED_)

View file

@ -1,139 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "win_image.h"
#define INITGUID
#include <initguid.h>
#include <Imaging.h>
#pragma comment(lib, "imaging")
/* TODO: those only work on wince 5.0 so we should have fallback for
earlier versions */
struct win_image {
IImage * image;
int dx;
int dy;
};
win_image *win_image_from_file(const TCHAR *file_path)
{
IImagingFactory* imageFactory;
ImageInfo info;
win_image * img = NULL;
img = SAZ(win_image);
if (!img)
return NULL;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr = CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER,
IID_IImagingFactory, (LPVOID*)&imageFactory);
if (FAILED(hr))
goto Error;
hr = imageFactory->CreateImageFromFile(file_path, &img->image);
imageFactory->Release();
if (FAILED(hr))
goto Error;
img->image->GetImageInfo(&info);
img->dx = info.Width;
img->dy = info.Height;
return img;
Error:
win_image_delete(img);
return NULL;
}
win_image * win_image_from_buffer(void *buf, UINT buf_size)
{
IImagingFactory* imageFactory;
ImageInfo info;
win_image * img = NULL;
img = SAZ(win_image);
if (!img)
return NULL;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr = CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER,
IID_IImagingFactory, (LPVOID*)&imageFactory);
if (FAILED(hr))
goto Error;
hr = imageFactory->CreateImageFromBuffer(buf, buf_size, BufferDisposalFlagNone, &img->image);
imageFactory->Release();
if (FAILED(hr))
goto Error;
img->image->GetImageInfo(&info);
img->dx = info.Width;
img->dy = info.Height;
return img;
Error:
win_image_delete(img);
return NULL;
}
win_image *win_image_from_resource(HMODULE hinst, int resource_id)
{
HRSRC hres;
void * buf;
DWORD res_size;
HGLOBAL hdata;
hres = FindResource(hinst, MAKEINTRESOURCE(resource_id), RT_RCDATA);
if (!hres)
return NULL;
res_size = SizeofResource(hinst, hres);
if (0 == res_size)
return NULL;
hdata = LoadResource(hinst, hres);
if (!hdata)
return NULL;
buf = (void*)LockResource(hdata);
if (!buf)
return NULL;
return win_image_from_buffer(buf, (UINT)res_size);
}
void win_image_delete(win_image *img)
{
assert(img);
if (!img)
return;
if (img->image)
img->image->Release();
free(img);
}
void win_image_blit_at(win_image *img, HDC dc, int x, int y)
{
RECT r = {0};
assert(img);
if (!img)
return;
assert(img->image);
if (!img->image)
return;
r.left = x;
r.right = x + img->dx;
r.top = y;
r.bottom = y + img->dy;
img->image->Draw(dc, &r, NULL);
}

View file

@ -1,23 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef WIN_IMAGE_H__
#define WIN_IMAGE_H__
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct win_image win_image;
win_image * win_image_from_file(const TCHAR *file_path);
win_image * win_image_from_buffer(void *buf, UINT buf_size);
win_image * win_image_from_resource(HMODULE hinst, int resource_id);
void win_image_delete(win_image *img);
void win_image_blit_at(win_image *img, HDC dc, int x, int y);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,463 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#include "base_util.h"
#include "win_util.h"
#include "tstr_util.h"
#ifdef _WIN32_WCE
#include <aygshell.h>
#include <Shlobj.h>
#endif
// Hmm, why have to redefine here (?!)
#ifdef __GNUC__
#define LVM_GETSELECTIONMARK (LVM_FIRST+66)
#define ListView_GetSelectionMark(w) (INT)SNDMSG((w),LVM_GETSELECTIONMARK,0,0)
#endif
int rect_dx(RECT *r)
{
int dx = r->right - r->left;
assert(dx >= 0);
return dx;
}
int rect_dy(RECT *r)
{
int dy = r->bottom - r->top;
assert(dy >= 0);
return dy;
}
void rect_set(RECT *r, int x, int y, int dx, int dy)
{
r->left = x;
r->top = y;
r->right = x + dx;
r->bottom = y + dy;
}
void win_set_font(HWND hwnd, HFONT font)
{
SendMessage(hwnd, WM_SETFONT, (WPARAM)font, 0);
}
int win_get_text_len(HWND hwnd)
{
return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
}
void win_set_text(HWND hwnd, const TCHAR *txt)
{
SendMessage(hwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)txt);
}
/* return a text in edit control represented by hwnd
return NULL in case of error (couldn't allocate memory)
caller needs to free() the text */
TCHAR *win_get_text(HWND hwnd)
{
int cchTxtLen = win_get_text_len(hwnd);
TCHAR * txt = (TCHAR*)malloc((cchTxtLen+1)*sizeof(TCHAR));
if (NULL == txt)
return NULL;
SendMessage(hwnd, WM_GETTEXT, cchTxtLen + 1, (LPARAM)txt);
txt[cchTxtLen] = 0;
return txt;
}
void win_edit_set_selection(HWND hwnd, DWORD selStart, DWORD selEnd)
{
SendMessage(hwnd, EM_SETSEL, (WPARAM)selStart, (WPARAM)selEnd);
}
void win_edit_select_all(HWND hwnd)
{
win_edit_set_selection(hwnd, 0, -1);
}
LRESULT lv_delete_all_items(HWND hwnd)
{
return SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0);
}
LRESULT lv_set_items_count(HWND hwnd, int items_count)
{
#ifdef __GNUC__
ListView_SetItemCount(hwnd, items_count);
#else
return ListView_SetItemCount(hwnd, items_count);
#endif
}
int lv_get_items_count(HWND hwnd)
{
LRESULT count = ListView_GetItemCount(hwnd);
if (LB_ERR == count)
return 0;
return (int)count;
}
LRESULT lv_insert_column(HWND hwnd, int col, LVCOLUMN *lvc)
{
return SendMessage(hwnd, LVM_INSERTCOLUMN, col, (LPARAM)lvc);
}
LRESULT lv_set_column(HWND hwnd, int col, LVCOLUMN *lvc)
{
return SendMessage(hwnd, LVM_SETCOLUMN, col, (LPARAM)lvc);
}
LRESULT lv_set_column_dx(HWND hwnd, int col, int dx)
{
return ListView_SetColumnWidth(hwnd, col, dx);
}
LRESULT lv_insert_item(HWND hwnd, int row, LVITEM *lvi)
{
lvi->iItem = row;
lvi->iSubItem = 0;
return SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM)lvi);
}
LRESULT lb_delete_string(HWND hwnd, int pos)
{
return SendMessage(hwnd, LB_DELETESTRING, pos, 0);
}
LRESULT lb_delete_all_items(HWND hwnd)
{
#if 1
LRESULT remaining_count;
for (;;) {
remaining_count = lb_delete_string(hwnd, 0);
if ((LB_ERR == remaining_count) || (0 == remaining_count))
break;
}
return 0;
#else
LRESULT count;
int i;
count = lb_get_items_count(hwnd);
if (LB_ERR == count)
return LB_ERR;
for (i=count-1; i--; i>=0) {
lb_delete_string(hwnd, i);
}
assert(0 == lb_get_items_count(hwnd);
#endif
}
#if 0
LRESULT lb_set_items_count(HWND hwnd, int items_count)
{
return SendMessage(hwnd, LB_SETCOUNT, items_count, 0);
}
#endif
LRESULT lb_get_items_count(HWND hwnd)
{
return SendMessage(hwnd, LB_GETCOUNT, 0, 0);
}
LRESULT lb_insert_item_text(HWND hwnd, int row, const TCHAR *txt)
{
return SendMessage(hwnd, LB_INSERTSTRING, (WPARAM)row, (LPARAM)txt);
}
LRESULT lb_append_string_no_sort(HWND hwnd, const TCHAR *txt)
{
return lb_insert_item_text(hwnd, -1, txt);
}
/* lb_get_selection and lb_set_selection only work for single-selection listbox */
LRESULT lb_get_selection(HWND hwnd)
{
return SendMessage(hwnd, LB_GETCURSEL, 0, 0);
}
LRESULT lb_set_selection(HWND hwnd, int item)
{
assert(item >= 0);
return SendMessage(hwnd, LB_SETCURSEL, (WPARAM)item, 0);
}
LRESULT lv_insert_item_text(HWND hwnd, int row, const TCHAR *txt)
{
LVITEM lvi = {0};
assert(txt);
if (!txt)
return -1; /* means failure */
lvi.mask = LVIF_TEXT;
lvi.pszText = (LPTSTR)txt;
return lv_insert_item(hwnd, row, &lvi);
}
/* Returns a selected item or -1 if no selection.
Assumes that the list is single-sel */
int lv_get_selection_pos(HWND hwnd)
{
int selection;
int selected_count = ListView_GetSelectedCount(hwnd);
assert(selected_count <= 1);
if (0 == selected_count)
return -1;
selection = ListView_GetSelectionMark(hwnd);
return selection;
}
int font_get_dy_from_dc(HDC hdc, HFONT font)
{
TEXTMETRIC tm;
HFONT font_prev;
int font_dy;
font_prev = (HFONT)SelectObject(hdc, font);
GetTextMetrics(hdc, &tm);
font_dy = tm.tmAscent + tm.tmDescent;
SelectObject(hdc, font_prev);
return font_dy;
}
int font_get_dy(HWND hwnd, HFONT font)
{
HDC hdc;
int font_dy = 0;
hdc = GetDC(hwnd);
if (hdc)
font_dy = font_get_dy_from_dc(hdc, font);
ReleaseDC(hwnd, hdc);
return font_dy;
}
#ifdef _WIN32_WCE
/* see http://pocketpcdn.com/articles/wordcompletion.html for details
edit boxes on pocket pc by default have spelling suggestion/completion.
Sometimes we want/need to disable that and this is a function to do it. */
void sip_completion_disable(void)
{
SIPINFO info;
SHSipInfo(SPI_GETSIPINFO, 0, &info, 0);
info.fdwFlags |= SIPF_DISABLECOMPLETION;
SHSipInfo(SPI_SETSIPINFO, 0, &info, 0);
}
void sip_completion_enable(void)
{
SIPINFO info;
SHSipInfo(SPI_GETSIPINFO, 0, &info, 0);
info.fdwFlags &= ~SIPF_DISABLECOMPLETION;
SHSipInfo(SPI_SETSIPINFO, 0, &info, 0);
}
#endif
void launch_url(const TCHAR *url)
{
SHELLEXECUTEINFO sei;
BOOL res;
if (NULL == url)
return;
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_FLAG_NO_UI;
sei.lpVerb = TEXT("open");
sei.lpFile = url;
sei.nShow = SW_SHOWNORMAL;
res = ShellExecuteEx(&sei);
return;
}
/* On windows those are defined as:
#define CSIDL_PROGRAMS 0x0002
#define CSIDL_PERSONAL 0x0005
#define CSIDL_APPDATA 0x001a
see shlobj.h for more */
#ifdef CSIDL_APPDATA
/* this doesn't seem to be defined on sm 2002 */
#define SPECIAL_FOLDER_PATH CSIDL_APPDATA
#endif
#ifdef CSIDL_PERSONAL
/* this is defined on sm 2002 and goes to "\My Documents".
Not sure if I should use it */
#ifndef SPECIAL_FOLDER_PATH
#define SPECIAL_FOLDER_PATH CSIDL_PERSONAL
#endif
#endif
/* see http://www.opennetcf.org/Forums/post.asp?method=TopicQuote&TOPIC_ID=95&FORUM_ID=12
for more possibilities
return false on failure, true if ok. Even if returns false, it'll return root ("\")
directory so that clients can ignore failures from this function
*/
TCHAR *get_app_data_folder_path(BOOL f_create)
{
#ifdef SPECIAL_FOLDER_PATH
BOOL f_ok;
TCHAR path[MAX_PATH];
f_ok = SHGetSpecialFolderPath(NULL, path, SPECIAL_FOLDER_PATH, f_create);
if (f_ok)
return tstr_dup(path);
else
return tstr_dup(_T(""));
#else
/* if all else fails, just use root ("\") directory */
return (TCHAR*)str_dup(_T("")); /* @note: mingw doesn't support tstr_dup */
#endif
}
void screen_get_dx_dy(int *dx_out, int *dy_out)
{
if (dx_out)
*dx_out = GetSystemMetrics(SM_CXSCREEN);
if (dy_out)
*dy_out = GetSystemMetrics(SM_CYSCREEN);
}
int screen_get_dx(void)
{
return (int)GetSystemMetrics(SM_CXSCREEN);
}
int screen_get_dy(void)
{
return (int)GetSystemMetrics(SM_CYSCREEN);
}
int screen_get_menu_dy(void)
{
return GetSystemMetrics(SM_CYMENU);
}
int screen_get_caption_dy(void)
{
return GetSystemMetrics(SM_CYCAPTION);
}
/* given a string id 'strId' from resources, get the string in a dynamically
allocated string.
Returns the string or NULL if error.
Caller needs to free() the string.
TODO: string is limited to BUF_CCH_SIZE. Could do it better by dynamically
allocating more memory if needed */
#define BUF_CCH_SIZE 256
TCHAR *load_string_dup(int str_id)
{
TCHAR buf[BUF_CCH_SIZE] = {0};
LoadString(NULL, str_id, buf, BUF_CCH_SIZE);
if (0 == tstr_len(buf))
{
assert(0);
return NULL;
}
return (TCHAR*)str_dup(buf); /* @note: mingw doesn't support tstr_dup */
}
const TCHAR *load_string(int str_id)
{
int res;
const TCHAR *str;
/* little-known hack: when lpBuffer is NULL, LoadString() returns
a pointer to a string, that can be cast to TCHAR * (LPCTSTR)
requires -n option to RC (resource compiler)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdk40/html/cerefLoadString.asp */
res = LoadString(NULL, str_id, NULL, 0);
if (0 == res)
return NULL;
str = (const TCHAR*)res;
return str;
}
// A helper to set a string, null-terminated 'keyValue' for a given 'keyName'
// in 'keyPath'/'keyClass'
// if 'keyName' is NULL then we set the default value for 'keyPath'
// Returns false if there was any error (can be ignored)
int regkey_set_str(HKEY key_class, TCHAR *key_path, TCHAR *key_name, TCHAR *key_value)
{
HKEY hkey = NULL;
DWORD size = 0;
BOOL f_ok;
if (ERROR_SUCCESS != RegCreateKeyEx(key_class, key_path, 0, NULL, 0, 0, NULL, &hkey, NULL))
return FALSE;
f_ok = TRUE;
size = (DWORD)(tstr_len(key_value)*sizeof(TCHAR));
if (ERROR_SUCCESS != RegSetValueEx(hkey, key_name, 0, REG_SZ, (LPBYTE)key_value, size))
f_ok = FALSE;
RegCloseKey(hkey);
return f_ok;
}
int regkey_set_dword(HKEY key_class, TCHAR *key_path, TCHAR *key_name, DWORD key_value)
{
HKEY hkey = NULL;
DWORD size = 0;
BOOL f_ok;
if (ERROR_SUCCESS != RegCreateKeyEx(key_class, key_path, 0, NULL, 0, 0, NULL, &hkey, NULL))
return FALSE;
f_ok = TRUE;
size = sizeof(DWORD);
if (ERROR_SUCCESS != RegSetValueEx(hkey, key_name, 0, REG_DWORD, (LPBYTE)&key_value, size))
f_ok = FALSE;
RegCloseKey(hkey);
return f_ok;
}
static void rect_client_to_screen(RECT *r, HWND hwnd)
{
POINT p1 = {r->left, r->top};
POINT p2 = {r->right, r->bottom};
ClientToScreen(hwnd, &p1);
ClientToScreen(hwnd, &p2);
r->left = p1.x;
r->top = p1.y;
r->right = p2.x;
r->bottom = p2.y;
}
void paint_round_rect_around_hwnd(HDC hdc, HWND hwnd_edit_parent, HWND hwnd_edit, COLORREF col)
{
RECT r;
HBRUSH br;
HBRUSH br_prev;
HPEN pen;
HPEN pen_prev;
GetClientRect(hwnd_edit, &r);
br = CreateSolidBrush(col);
if (!br) return;
pen = CreatePen(PS_SOLID, 1, col);
pen_prev = SelectObject(hdc, pen);
br_prev = SelectObject(hdc, br);
rect_client_to_screen(&r, hwnd_edit_parent);
/* TODO: the roundness value should probably be calculated from the dy of the rect */
/* TODO: total hack: I manually adjust rectangle to values that fit g_hwnd_edit, as
found by experimentation. My mapping of coordinates isn't right (I think I need
mapping from window to window but even then it wouldn't explain -3 for y axis */
RoundRect(hdc, r.left+4, r.top-3, r.right+12, r.bottom-3, 8, 8);
if (br_prev)
SelectObject(hdc, br_prev);
if (pen_prev)
SelectObject(hdc, pen_prev);
DeleteObject(pen);
DeleteObject(br);
}

View file

@ -1,128 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef WIN_UTIL_H_
#define WIN_UTIL_H_
#include <commctrl.h>
/* Utilities to help in common windows programming tasks */
#ifdef __cplusplus
extern "C"
{
#endif
/* constant to make it easier to return proper LRESULT values when handling
various windows messages */
#define WM_KILLFOCUS_HANDLED 0
#define WM_SETFOCUS_HANDLED 0
#define WM_KEYDOWN_HANDLED 0
#define WM_KEYUP_HANDLED 0
#define WM_LBUTTONDOWN_HANDLED 0
#define WM_LBUTTONUP_HANDLED 0
#define WM_PAINT_HANDLED 0
#define WM_DRAWITEM_HANDLED TRUE
#define WM_MEASUREITEM_HANDLED TRUE
#define WM_SIZE_HANDLED 0
#define LVN_ITEMACTIVATE_HANDLED 0
#define WM_VKEYTOITEM_HANDLED_FULLY -2
#define WM_VKEYTOITEM_NOT_HANDLED -1
#define WM_CREATE_OK 0
#define WM_CREATE_FAILED -1
#define WIN_COL_RED RGB(255,0,0)
#define WIN_COL_WHITE RGB(255,255,255)
#define WIN_COL_BLACK RGB(0,0,0)
#define WIN_COL_BLUE RGB(0,0,255)
#define WIN_COL_GREEN RGB(0,255,0)
#define WIN_COL_GRAY RGB(215,215,215)
int rect_dx(RECT *r);
int rect_dy(RECT *r);
void rect_set(RECT *r, int x, int y, int dx, int dy);
void win_set_font(HWND hwnd, HFONT font);
int win_get_text_len(HWND hwnd);
TCHAR * win_get_text(HWND hwnd);
void win_set_text(HWND hwnd, const TCHAR *txt);
void win_edit_set_selection(HWND hwnd, DWORD selStart, DWORD selEnd);
void win_edit_select_all(HWND hwnd);
LRESULT lv_delete_all_items(HWND hwnd);
LRESULT lv_set_items_count(HWND hwnd, int items_count);
int lv_get_items_count(HWND hwnd);
LRESULT lv_insert_column(HWND hwnd, int col, LVCOLUMN *lvc);
LRESULT lv_set_column(HWND hwnd, int col, LVCOLUMN *lvc);
LRESULT lv_set_column_dx(HWND hwnd, int col, int dx);
LRESULT lv_insert_item(HWND hwnd, int row, LVITEM *lvi);
LRESULT lv_insert_item_text(HWND hwnd, int row, const TCHAR *txt);
int lv_get_selection_pos(HWND hwnd);
LRESULT lb_delete_all_items(HWND hwnd);
#if 0 /* doesn't seem to be supported under wince */
LRESULT lb_set_items_count(HWND hwnd, int items_count);
#endif
LRESULT lb_insert_item_text(HWND hwnd, int row, const TCHAR *txt);
LRESULT lb_append_string_no_sort(HWND hwnd, const TCHAR *txt);
LRESULT lb_get_items_count(HWND hwnd);
LRESULT lb_set_selection(HWND hwnd, int item);
LRESULT lb_get_selection(HWND hwnd);
int font_get_dy(HWND hwnd, HFONT font);
int font_get_dy_from_dc(HDC hdc, HFONT font);
void screen_get_dx_dy(int *dx_out, int *dy_out);
int screen_get_dx(void);
int screen_get_dy(void);
int screen_get_menu_dy(void);
int screen_get_caption_dy(void);
#ifdef _WIN32_WCE
void sip_completion_disable(void);
void sip_completion_enable(void);
#endif
void launch_url(const TCHAR *url);
TCHAR * get_app_data_folder_path(BOOL f_create);
TCHAR * load_string_dup(int str_id);
const TCHAR *load_string(int str_id);
int regkey_set_dword(HKEY key_class, TCHAR *key_path, TCHAR *key_name, DWORD key_value);
int regkey_set_str(HKEY key_class, TCHAR *key_path, TCHAR *key_name, TCHAR *key_value);
void paint_round_rect_around_hwnd(HDC hdc, HWND hwnd_edit_parent, HWND hwnd_edit, COLORREF col);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
class AppBarData {
public:
AppBarData() {
m_abd.cbSize = sizeof(m_abd);
/* default values for the case of SHAppBarMessage() failing
(shouldn't really happen) */
RECT rc = {0, 0, 0, 0};
m_abd.rc = rc;
m_abd.uEdge = ABE_TOP;
SHAppBarMessage(ABM_GETTASKBARPOS, &m_abd);
}
int dx() { return rect_dx(&m_abd.rc); }
int dy() { return rect_dy(&m_abd.rc); }
int x() { return m_abd.rc.left; }
int y() { return m_abd.rc.top; }
bool atTop() { return ABE_TOP == m_abd.uEdge; }
bool atBottom() { return ABE_BOTTOM == m_abd.uEdge; }
bool atLeft() { return ABE_LEFT == m_abd.uEdge; }
bool atRight() { return ABE_RIGHT == m_abd.uEdge; }
bool isHorizontal() { return atLeft() || atRight(); }
bool isVertical() { return atBottom() || atTop(); }
private:
APPBARDATA m_abd;
};
#endif
#endif

View file

@ -1,285 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
/* The most basic things, including string handling functions */
#include "base_util.h"
#include "wstr_util.h"
#include <strsafe.h>
WCHAR *wstr_cat4(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3, const WCHAR *str4)
{
WCHAR *str;
WCHAR *tmp;
size_t str1_len = 0;
size_t str2_len = 0;
size_t str3_len = 0;
size_t str4_len = 0;
if (str1)
str1_len = wstrlen(str1);
if (str2)
str2_len = wstrlen(str2);
if (str3)
str3_len = wstrlen(str3);
if (str4)
str4_len = wstrlen(str4);
str = (WCHAR*)zmalloc((str1_len + str2_len + str3_len + str4_len + 1)*sizeof(WCHAR));
if (!str)
return NULL;
tmp = str;
if (str1) {
memcpy(tmp, str1, str1_len*sizeof(WCHAR));
tmp += str1_len;
}
if (str2) {
memcpy(tmp, str2, str2_len*sizeof(WCHAR));
tmp += str2_len;
}
if (str3) {
memcpy(tmp, str3, str3_len*sizeof(WCHAR));
tmp += str3_len;
}
if (str4) {
memcpy(tmp, str4, str1_len*sizeof(WCHAR));
}
return str;
}
WCHAR *wstr_cat3(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3)
{
return wstr_cat4(str1, str2, str3, NULL);
}
WCHAR *wstr_cat(const WCHAR *str1, const WCHAR *str2)
{
return wstr_cat4(str1, str2, NULL, NULL);
}
WCHAR *wstr_dupn(const WCHAR *str, int str_len_cch)
{
WCHAR *copy;
if (!str)
return NULL;
copy = (WCHAR*)malloc((str_len_cch+1)*sizeof(WCHAR));
if (!copy)
return NULL;
memcpy(copy, str, str_len_cch*sizeof(WCHAR));
copy[str_len_cch] = 0;
return copy;
}
WCHAR *wstr_dup(const WCHAR *str)
{
return wstr_cat4(str, NULL, NULL, NULL);
}
int wstr_copyn(WCHAR *dst, int dst_cch_size, const WCHAR *src, int src_cch_size)
{
WCHAR *end = dst + dst_cch_size - 1;
if (0 == dst_cch_size) {
if (0 == src_cch_size)
return TRUE;
else
return FALSE;
}
while ((dst < end) && (src_cch_size > 0)) {
*dst++ = *src++;
--src_cch_size;
}
*dst = 0;
if (0 == src_cch_size)
return TRUE;
else
return FALSE;
}
int wstr_copy(WCHAR *dst, int dst_cch_size, const WCHAR *src)
{
WCHAR *end = dst + dst_cch_size - 1;
if (0 == dst_cch_size)
return FALSE;
while ((dst < end) && *src) {
*dst++ = *src++;
}
*dst = 0;
if (0 == *src)
return TRUE;
else
return FALSE;
}
int wstr_ieq(const WCHAR *str1, const WCHAR *str2)
{
if (!str1 && !str2)
return TRUE;
if (!str1 || !str2)
return FALSE;
if (0 == _wcsicmp(str1, str2))
return TRUE;
return FALSE;
}
/* return true if 'str' starts with 'txt', case-sensitive */
int wstr_startswith(const WCHAR *str, const WCHAR *txt)
{
if (!str && !txt)
return TRUE;
if (!str || !txt)
return FALSE;
if (0 == wcsncmp(str, txt, wcslen(txt)))
return TRUE;
return FALSE;
}
/* return true if 'str' starts with 'txt', NOT case-sensitive */
int wstr_startswithi(const WCHAR *str, const WCHAR *txt)
{
if (!str && !txt)
return TRUE;
if (!str || !txt)
return FALSE;
if (0 == _wcsnicmp(str, txt, wcslen(txt)))
return TRUE;
return FALSE;
}
int wstr_empty(const WCHAR *str)
{
if (!str)
return TRUE;
if (0 == *str)
return TRUE;
return FALSE;
}
static void wchar_to_hex(WCHAR c, WCHAR* buffer)
{
const WCHAR* numbers = L"0123456789ABCDEF";
buffer[0]=numbers[c / 16];
buffer[1]=numbers[c % 16];
}
int wstr_contains(const WCHAR *str, WCHAR c)
{
while (*str) {
if (c == *str++)
return TRUE;
}
return FALSE;
}
#define WCHAR_URL_DONT_ENCODE L"-_.!~*'()"
int wchar_needs_url_encode(WCHAR c)
{
if ((c >= L'a') && (c <= L'z'))
return FALSE;
if ((c >= L'A') && (c <= L'Z'))
return FALSE;
if ((c >= L'0') && (c <= L'9'))
return FALSE;
if (wstr_contains(WCHAR_URL_DONT_ENCODE, c))
return FALSE;
return TRUE;
}
WCHAR *wstr_url_encode(const WCHAR *str)
{
WCHAR * encoded;
WCHAR * result;
int res_len = 0;
const WCHAR * tmp = str;
while (*tmp) {
if (wchar_needs_url_encode(*tmp))
res_len += 3;
else
++res_len;
tmp++;
}
if (0 == res_len)
return NULL;
encoded = (WCHAR*)malloc((res_len+1)*sizeof(WCHAR));
if (!encoded)
return NULL;
result = encoded;
tmp = str;
while (*tmp) {
if (wchar_needs_url_encode(*tmp)) {
*encoded++ = L'%';
wchar_to_hex(*tmp, encoded);
encoded += 2;
} else {
if (L' ' == *tmp)
*encoded++ = L'+';
else
*encoded++ = *tmp;
}
tmp++;
}
*encoded = 0;
return result;
}
WCHAR *wstr_printf(const WCHAR *format, ...)
{
HRESULT hr;
va_list args;
WCHAR message[256];
WCHAR * buf;
size_t bufCchSize;
buf = &(message[0]);
bufCchSize = sizeof(message)/sizeof(message[0]);
va_start(args, format);
for (;;)
{
hr = StringCchVPrintfW(buf, bufCchSize, format, args);
if (S_OK == hr)
break;
if (STRSAFE_E_INSUFFICIENT_BUFFER != hr)
{
/* any error other than buffer not big enough:
a) should not happen
b) means we give up */
assert(FALSE);
goto Error;
}
/* we have to make the buffer bigger. The algorithm used to calculate
the new size is arbitrary (aka. educated guess) */
if (buf != &(message[0]))
free(buf);
if (bufCchSize < 4*1024)
bufCchSize += bufCchSize;
else
bufCchSize += 1024;
buf = (WCHAR *)malloc(bufCchSize*sizeof(WCHAR));
if (NULL == buf)
goto Error;
}
va_end(args);
/* free the buffer if it was dynamically allocated */
if (buf == &(message[0]))
return wstr_dup(buf);
return buf;
Error:
if (buf != &(message[0]))
free((void*)buf);
return NULL;
}

View file

@ -1,35 +0,0 @@
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
The author disclaims copyright to this source code. */
#ifndef WSTR_UTIL_H_
#define WSTR_UTIL_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define wstrlen wcslen
int wstr_ieq(const WCHAR *str1, const WCHAR *str2);
int wstr_startswith(const WCHAR *str, const WCHAR *txt);
int wstr_startswithi(const WCHAR *str, const WCHAR *txt);
int wstr_empty(const WCHAR *str);
int wstr_copy(WCHAR *dst, int dst_cch_size, const WCHAR *src);
int wstr_copyn(WCHAR *dst, int dst_cch_size, const WCHAR *src, int src_cch_size);
WCHAR * wstr_dup(const WCHAR *str);
WCHAR * wstr_dupn(const WCHAR *str, int str_len_cch);
WCHAR * wstr_cat(const WCHAR *str1, const WCHAR *str2);
WCHAR * wstr_cat3(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3);
WCHAR * wstr_cat4(const WCHAR *str1, const WCHAR *str2, const WCHAR *str3, const WCHAR *str4);
WCHAR * wstr_url_encode(const WCHAR *str);
WCHAR wchar_needs_url_escape(WCHAR c);
int wstr_contains(const WCHAR *str, WCHAR c);
WCHAR * wstr_printf(const WCHAR *format, ...);
#ifdef DEBUG
void wstr_util_test(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,167 +0,0 @@
<module name="fitz" type="staticlibrary" stdlib="host" allowwarnings="true">
<library>ntdll</library>
<library>kernel32</library>
<library>libjpeg</library>
<library>zlib</library>
<library>freetype</library>
<define name="HAVE_CONFIG_H" />
<define name="__USE_W32API" />
<define name="WIN32" />
<define name="_WIN32" />
<define name="_WINDOWS" />
<define name="UNICODE" />
<define name="_UNICODE" />
<define name="_DEBUG" />
<define name="DEBUG" />
<define name="NEED_MATH">1</define>
<define name="NEED_STRLCPY">1</define>
<define name="NEED_STRSEP">1</define>
<define name="inline"></define>
<define name="__REACTOS__" />
<define name="USE_GCC_PRAGMAS" />
<include base="libjpeg">.</include>
<include base="zlib">.</include>
<include base="freetype">include</include>
<include base="fitz">.</include>
<include>baseutils</include>
<include>fitz</include>
<include>fitz/fonts</include>
<include>fitz/include</include>
<include>fitz/include/fitz</include>
<include>fitz/include/mupdf</include>
<include>fitz/include/samus</include>
<include>fitz/base</include>
<include>fitz/stream</include>
<include>fitz/raster</include>
<include>fitz/world</include>
<include>fitz/mupdf</include>
<directory name="fitz">
<directory name="fonts">
<file>Dingbats.cff.c</file>
<file>NimbusMonL-Bold.cff.c</file>
<file>NimbusMonL-BoldObli.cff.c</file>
<file>NimbusMonL-Regu.cff.c</file>
<file>NimbusMonL-ReguObli.cff.c</file>
<file>NimbusRomNo9L-Medi.cff.c</file>
<file>NimbusRomNo9L-MediItal.cff.c</file>
<file>NimbusRomNo9L-Regu.cff.c</file>
<file>NimbusRomNo9L-ReguItal.cff.c</file>
<file>NimbusSanL-Bold.cff.c</file>
<file>NimbusSanL-BoldItal.cff.c</file>
<file>NimbusSanL-Regu.cff.c</file>
<file>NimbusSanL-ReguItal.cff.c</file>
<file>StandardSymL.cff.c</file>
<file>URWChanceryL-MediItal.cff.c</file>
</directory>
<directory name="base">
<file>base_cpudep.c</file>
<file>base_error.c</file>
<file>base_hash.c</file>
<file>base_matrix.c</file>
<file>base_memory.c</file>
<file>base_rect.c</file>
<file>base_rune.c</file>
<file>util_getopt.c</file>
<file>util_strlcat.c</file>
<file>util_strlcpy.c</file>
<file>util_strsep.c</file>
</directory>
<directory name="stream">
<file>crypt_arc4.c</file>
<file>crypt_crc32.c</file>
<file>crypt_md5.c</file>
<file>filt_a85d.c</file>
<file>filt_a85e.c</file>
<file>filt_ahxd.c</file>
<file>filt_ahxe.c</file>
<file>filt_arc4.c</file>
<file>filt_dctd.c</file>
<file>filt_dcte.c</file>
<file>filt_faxd.c</file>
<file>filt_faxdtab.c</file>
<file>filt_faxe.c</file>
<file>filt_faxetab.c</file>
<file>filt_flate.c</file>
<file>filt_lzwd.c</file>
<file>filt_lzwe.c</file>
<file>filt_null.c</file>
<file>filt_pipeline.c</file>
<file>filt_predict.c</file>
<file>filt_rld.c</file>
<file>filt_rle.c</file>
<file>obj_array.c</file>
<file>obj_dict.c</file>
<file>obj_parse.c</file>
<file>obj_print.c</file>
<file>obj_simple.c</file>
<file>stm_buffer.c</file>
<file>stm_filter.c</file>
<file>stm_misc.c</file>
<file>stm_open.c</file>
<file>stm_read.c</file>
<file>stm_write.c</file>
</directory>
<directory name="raster">
<file>glyphcache.c</file>
<file>imagedraw.c</file>
<file>imagescale.c</file>
<file>imageunpack.c</file>
<file>meshdraw.c</file>
<file>pathfill.c</file>
<file>pathscan.c</file>
<file>pathstroke.c</file>
<file>pixmap.c</file>
<file>porterduff.c</file>
<file>render.c</file>
</directory>
<directory name="world">
<file>node_misc1.c</file>
<file>node_misc2.c</file>
<file>node_optimize.c</file>
<file>node_path.c</file>
<file>node_text.c</file>
<file>node_tree.c</file>
<file>res_colorspace.c</file>
<file>res_font.c</file>
<file>res_image.c</file>
<file>res_shade.c</file>
</directory>
<directory name="mupdf">
<file>pdf_annot.c</file>
<file>pdf_build.c</file>
<file>pdf_cmap.c</file>
<file>pdf_colorspace1.c</file>
<file>pdf_colorspace2.c</file>
<file>pdf_crypt.c</file>
<file>pdf_debug.c</file>
<file>pdf_doctor.c</file>
<file>pdf_font.c</file>
<file>pdf_fontagl.c</file>
<file>pdf_fontenc.c</file>
<file>pdf_fontfile.c</file>
<file>pdf_function.c</file>
<file>pdf_image.c</file>
<file>pdf_interpret.c</file>
<file>pdf_lex.c</file>
<file>pdf_nametree.c</file>
<file>pdf_open.c</file>
<file>pdf_outline.c</file>
<file>pdf_page.c</file>
<file>pdf_pagetree.c</file>
<file>pdf_parse.c</file>
<file>pdf_pattern.c</file>
<file>pdf_repair.c</file>
<file>pdf_resources.c</file>
<file>pdf_save.c</file>
<file>pdf_shade.c</file>
<file>pdf_shade1.c</file>
<file>pdf_shade4.c</file>
<file>pdf_store.c</file>
<file>pdf_stream.c</file>
<file>pdf_type3.c</file>
<file>pdf_unicode.c</file>
<file>pdf_xobject.c</file>
<file>pdf_xref.c</file>
</directory>
</directory>
</module>

View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -1,199 +0,0 @@
In implementing the Metro parser on top of Fitz, and with the new
road map, I am facing the task of designing the API for managing
resources in Fitz. Up till now I have punted on making any final
decisions, exploring as I go. Now I feel that I cannot do so much longer.
Therefore I would like to hear your opinions and ideas on this.
Please brainstorm and point out any missing pieces.
First, a ten mile high overview of the Fitz architecture and
nomenclature, for those of you who are not in the loop or need
a refresher :)
The Fitz world is a set of resources. There are many kinds of resources.
Resources can depend on other resources, but no circular dependencies.
The resource types are: tree, font, image, shade, and colorspace.
A document is a sequence of tree resources that define the contents
of its pages.
A front-end is a producer of Fitz worlds, that reads a file and
creates a Fitz world from its contents. Abstracting this into
a high-level interface is useful primarily for viewers and
converters.
A back-end is a consumer of Fitz worlds. The default rasterizer
is one back-end. PDF writers and other output drivers too.
I don't think there should be a special interface for these.
They are just functions or programs that take the Fitz world
and do something unspecified with it.
The resource API is what I need help fleshing out. Keep in mind
that a Fitz world should be able to be serialized to disk, so having
callbacks and other hooks into the front-end is a no no. If it weren't
for this, my life would be a lot simpler :)
Both creation, querying, and on-disk format.
--------------------------------------------------------------------
TREE
The Fitz tree resource is the primary data structure.
A tree consists of nodes. There are leaf nodes and branch
nodes. Leaf nodes produce images, branch nodes combine
or change images. An image here is a two-dimensional
region of color and shape (alpha).
LEAF NODES
SOLID.
A constant color or shape that stretches out to infinity.
IMAGE.
A rectangular region of color and or shape derived
a from a grid of samples.
Outside this rectangle is transparent.
References an image resource.
SHADE.
A mesh of patches that define a region of interpolated colors.
Outside the mesh is transparent.
References a shade resource.
PATH.
A path defines only shape.
Moveto, lineto, curveto and closepath.
Stroke, fill, even-odd-fill.
Dash patterns.
TEXT.
A text node is an optimization, space-effectively combining
a transform matrix and references to glyph shapes.
Text nodes define only shape.
Text nodes have a b c d coefficients and a reference to a font.
Then an array of glyph index and e and f coefficient tuples.
Text nodes may also have a separate unicode array,
associating the (glyph,e,f) tuples with unicode character codes.
One-to-many and many-to-one mappings are allowed.
For text search and copy.
BRANCH NODES
TRANSFORM.
Transform nodes apply an affine transform matrix to
its one and only child.
OVER.
An over node stacks its children on top of each other,
combining their colors with a blending mode.
MASK.
A mask node has two children. The second child is masked
with the first child, multiplying their shapes.
This causes the effect of clipping.
(mask
(path ...)
(solid 'devicegray 0))
BLEND.
This does the magic of PDF 1.4 transparency.
The isolated and non-isolated and
knockout group stuff happens here.
It also sets the blend mode for its children.
LINK.
This is a dummy node that grafts in another
tree resource. The effect is as if the other
tree was copied here instead.
References a tree resource.
META.
A way to insert application specific data.
Transparent to the rasterizer, but can be
useful to preserve some non-Fitz semantics
that may be of use to specific producers/consumers
of Fitz trees. For example, tiling patterns
would be represented as an over node with
many transform and link nodes stamping out
the pattern to fill the page. Putting these
under an appropriate Meta node would allow
a PDF or Postscript backend to detect and
recreate the tiling pattern.
(meta 'pattern "...tiling pattern info..."
(over
(transform 1 0 0 1 0 0 (link 'pat1))
(transform 1 0 0 1 0 1 (link 'pat1))
(transform 1 0 0 1 1 0 (link 'pat1))
(transform 1 0 0 1 1 1 (link 'pat1))))
--------------------------------------------------------------------
COLORSPACES.
A colorspace needs the capability to transform colors into
and out of any other colorspace. I suggest that this happens
by going either through a standard colorspace (CIE XYZ),
or by having an optional A-to-B shortcut transform.
I am thinking of three sub-classes:
Device colors. Fast and dirty: Gray, RGB, CMYK only.
ICC Profiles. I am not very familiar with this.
Use Argyll? Are they easy to create programmatically
to represent the Cal* and L*a*b colorspaces?
Separation. For Separation and DeviceN.
This is a list of named colors, with backend
specific tailoring required to make sense of it. Also has
an alternate colorspace (Device or ICC) with a transform.
How do we represent the transform function?
SHADES.
This is fairly simple. A mesh of patches as in PDF.
Three levels of detail: with full tensors, with only patches,
with linear quads. Axial and radial shadings are trivially
converted. Type 1 (functional) shadings need to be sampled.
If the backends cannot cope, it can either convert to
linear shaded triangles (clip an axial shading with a triangular
path) or render to an image.
FONTS.
There need to be four types of font resources.
For now I am going to use FreeType, but that should not be a necessity.
The resource format for fonts should be independent.
* Fake fonts for substituted fonts. Refer to another fall-back
font resource and override the metrics.
Could possibly be represented as a type 3 font,
but knowing that it is a substitute may be useful.
* Type 3 fonts where each glyph is represented as a Fitz tree resource.
* Postscript fonts, in CFF format.
Type 1 and Type 1 CID fonts are losslessly convertible to CFF.
OpenType fonts can have CFF glyph data.
* TrueType fonts
IMAGES.
This is the tricky one. Raph, I forgot what we decided on the tiling.
What size, planar or chunky, etc. Which bit depths do we allow?
Image data should be chopped into tiles to allow for independent
and random access and more CPU-cache friendly image scaling and
color transforms.
* JPEG encoded images.
Save byte+bit offsets to allow random access to groups of eight scanlines.
* Monochrome images.
* Contone images.
The End

View file

@ -1,257 +0,0 @@
NULL=
BASEDIR=.
BINDIR=bin
!if "$(DEBUG)"=="1"
OBJDIR=obj-dbg
!else
OBJDIR=obj-rel
!endif
MUPDF=mupdf
FREETYPE_INC=$(BASEDIR)\windev\freetype_2_1_10\include
FREETYPE_LIB=$(BASEDIR)\windev\freetype_2_1_10
ZLIB_INC=$(BASEDIR)\windev\zlib
ZLIB_LIB=$(BASEDIR)\windev\zlib
JPEG_INC=$(BASEDIR)\windev\jpeg
JPEG_LIB=$(BASEDIR)\windev\jpeg
#DEBUG = 1
#
# Define compiler flags
#
CC = cl.exe
CFLAGS = $(CFLAGS) /nologo
CFLAGS = $(CFLAGS) /wd4996
CFLAGS = $(CFLAGS) /D "WIN32" /D "_WINDOWS" /D "_WIN32"
CFLAGS = $(CFLAGS) /D "_WIN32_WINNT=0x4000"
CFLAGS = $(CFLAGS) /D "NEED_MATH"
CFLAGS = $(CFLAGS) /D "_MBCS" /D "_REENTRANT" /W1 /GR-
CFLAGS = $(CFLAGS) /I$(BASEDIR)\include
CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\fitz
CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\mupdf
CFLAGS = $(CFLAGS) /I$(BASEDIR)\include\samus
CFLAGS = $(CFLAGS) /I$(FREETYPE_INC)
CFLAGS = $(CFLAGS) /I$(ZLIB_INC)
CFLAGS = $(CFLAGS) /I$(JPEG_INC)
# CFLAGS = /Ios-win32 /Fo$(OBJDIR)
!if "$(DEBUG)"=="1"
CFLAGS = $(CFLAGS) /D "_DEBUG" /MTd /Od /Zi
!else
CFLAGS = $(CFLAGS) /D "NDEBUG" /MT /Zi /O2 /GL /Oi /Ot /Oy /GF
!endif
#
# Define linker flags
#
LD = link.exe
LDFLAGS = $(LDFLAGS) /nologo
LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR)
LDFLAGS = $(LDFLAGS) /LIBPATH:$(FREETYPE_LIB)
LDFLAGS = $(LDFLAGS) /LIBPATH:$(ZLIB_LIB)
LDFLAGS = $(LDFLAGS) /LIBPATH:$(JPEG_LIB)
LDFLAGS = $(LDFLAGS) /SUBSYSTEM:WINDOWS
LIBS = $(LIBS) gdi32.lib comdlg32.lib advapi32.lib user32.lib shell32.lib kernel32.lib
!if "$(DEBUG)"=="1"
LIBS = $(LIBS) zlib_ds.lib freetype2110MT_D.lib jpeg_ds.lib
LDFLAGS = $(LDFLAGS) /DEBUG
!else
LDFLAGS = $(LDFLAGS) /OPT:NOWIN98 /LTCG /DEBUG
LIBS = $(LIBS) zlib_s.lib freetype2110MT.lib jpeg_s.lib
!endif
#
# Archiver flags
#
AR = lib.exe
ARFLAGS = $(ARFLAGS) /nologo
#
# mupdf.dll
#
MUPDF_DLL_OBJS= \
# this is stream
$(OBJDIR)\crypt_arc4.obj \
$(OBJDIR)\crypt_md5.obj \
$(OBJDIR)\filt_a85d.obj \
$(OBJDIR)\filt_ahxd.obj \
$(OBJDIR)\filt_arc4.obj \
$(OBJDIR)\filt_dctd.obj \
$(OBJDIR)\filt_faxd.obj \
$(OBJDIR)\filt_faxdtab.obj \
$(OBJDIR)\filt_faxe.obj \
$(OBJDIR)\filt_faxetab.obj \
$(OBJDIR)\filt_flate.obj \
$(OBJDIR)\filt_lzwd.obj \
$(OBJDIR)\filt_null.obj \
$(OBJDIR)\filt_pipeline.obj \
$(OBJDIR)\filt_predict.obj \
$(OBJDIR)\filt_rld.obj \
$(OBJDIR)\obj_array.obj \
$(OBJDIR)\obj_dict.obj \
$(OBJDIR)\obj_parse.obj \
$(OBJDIR)\obj_print.obj \
$(OBJDIR)\obj_simple.obj \
$(OBJDIR)\stm_filter.obj \
$(OBJDIR)\stm_buffer.obj \
$(OBJDIR)\stm_open.obj \
$(OBJDIR)\stm_misc.obj \
$(OBJDIR)\stm_read.obj \
$(OBJDIR)\stm_write.obj \
# this is for base
$(OBJDIR)\base_cpudep.obj \
$(OBJDIR)\base_error.obj \
$(OBJDIR)\base_hash.obj \
$(OBJDIR)\base_matrix.obj \
$(OBJDIR)\base_memory.obj \
$(OBJDIR)\base_rect.obj \
$(OBJDIR)\base_rune.obj \
$(OBJDIR)\util_getopt.obj \
$(OBJDIR)\util_strlcat.obj \
$(OBJDIR)\util_strlcpy.obj \
$(OBJDIR)\util_strsep.obj \
# this is for world
$(OBJDIR)\node_misc1.obj \
$(OBJDIR)\node_misc2.obj \
$(OBJDIR)\node_optimize.obj \
$(OBJDIR)\node_path.obj \
$(OBJDIR)\node_text.obj \
$(OBJDIR)\node_tree.obj \
$(OBJDIR)\res_colorspace.obj \
$(OBJDIR)\res_font.obj \
$(OBJDIR)\res_image.obj \
$(OBJDIR)\res_shade.obj \
# this is for raster
$(OBJDIR)\glyphcache.obj \
$(OBJDIR)\imagedraw.obj \
$(OBJDIR)\imagescale.obj \
$(OBJDIR)\imageunpack.obj \
$(OBJDIR)\meshdraw.obj \
$(OBJDIR)\pathfill.obj \
$(OBJDIR)\pathscan.obj \
$(OBJDIR)\pathstroke.obj \
$(OBJDIR)\pixmap.obj \
$(OBJDIR)\porterduff.obj \
$(OBJDIR)\render.obj \
# this is for draw
# $(OBJDIR)\draw_misc.obj \
# this mupdf
$(OBJDIR)\pdf_annot.obj \
$(OBJDIR)\pdf_build.obj \
$(OBJDIR)\pdf_cmap.obj \
$(OBJDIR)\pdf_colorspace1.obj \
$(OBJDIR)\pdf_colorspace2.obj \
$(OBJDIR)\pdf_crypt.obj \
$(OBJDIR)\pdf_debug.obj \
$(OBJDIR)\pdf_doctor.obj \
$(OBJDIR)\pdf_font.obj \
$(OBJDIR)\pdf_fontagl.obj \
$(OBJDIR)\pdf_fontenc.obj \
# $(OBJDIR)\pdf_fontfile.obj \
# $(OBJDIR)\pdf_fontfilefc.obj \
$(OBJDIR)\pdf_fontfilems.obj \
$(OBJDIR)\pdf_function.obj \
$(OBJDIR)\pdf_image.obj \
$(OBJDIR)\pdf_interpret.obj \
$(OBJDIR)\pdf_lex.obj \
$(OBJDIR)\pdf_nametree.obj \
$(OBJDIR)\pdf_open.obj \
$(OBJDIR)\pdf_outline.obj \
$(OBJDIR)\pdf_page.obj \
$(OBJDIR)\pdf_pagetree.obj \
$(OBJDIR)\pdf_parse.obj \
$(OBJDIR)\pdf_pattern.obj \
$(OBJDIR)\pdf_repair.obj \
$(OBJDIR)\pdf_resources.obj \
$(OBJDIR)\pdf_save.obj \
$(OBJDIR)\pdf_shade.obj \
$(OBJDIR)\pdf_shade1.obj \
$(OBJDIR)\pdf_shade4.obj \
$(OBJDIR)\pdf_store.obj \
$(OBJDIR)\pdf_stream.obj \
$(OBJDIR)\pdf_type3.obj \
$(OBJDIR)\pdf_unicode.obj \
$(OBJDIR)\pdf_xobject.obj \
$(OBJDIR)\pdf_xref.obj \
$(NULL)
MUPDF_EXE_OBJS= \
$(MUPDF_DLL_OBJS) \
$(OBJDIR)\pdfapp.obj \
$(OBJDIR)\winmain.obj \
$(NULL)
MUPDF_DLL_NAME=mupdf.dll
MUPDF_DLL_LIB_NAME=mupdf.lib
!if "$(DEBUG)"=="1"
MUPDF_EXE_NAME=mupdf-dbg.exe
MUPDF_PDB_NAME=mupdf-dbg.pdb
!else
MUPDF_EXE_NAME=mupdf.exe
MUPDF_PDB_NAME=mupdf.pdb
!endif
all: $(BINDIR)\$(MUPDF_EXE_NAME)
clean:
if exist $(BINDIR) rmdir /S /Q $(BINDIR)
if exist $(OBJDIR) rmdir /S /Q $(OBJDIR)
$(OBJDIR):
if not exist $(OBJDIR) mkdir $(OBJDIR)
$(BINDIR):
if not exist $(BINDIR) mkdir $(BINDIR)
#
# mupdf.dll
#
$(BINDIR)\$(MUPDF_DLL_NAME) : $(BINDIR) $(MUPDF_DLL_OBJS)
$(LD) $(LDFLAGS) /DLL \
/IMPLIB:$(BINDIR)\$(MUPDF_DLL_LIB_NAME) \
/OUT:$(BINDIR)\$(MUPDF_DLL_NAME) \
$(MUPDF_DLL_OBJS) $(LIBS)
$(OBJDIR)\winres.RES:
rc.exe /n /fo$(OBJDIR)\winres.RES apps\windows\winres.rc
$(BINDIR)\$(MUPDF_EXE_NAME) : $(BINDIR) $(MUPDF_EXE_OBJS) $(OBJDIR)\winres.RES
$(LD) $(LDFLAGS) \
/OUT:$(BINDIR)\$(MUPDF_EXE_NAME) \
/PDB:$(BINDIR)\$(MUPDF_PDB_NAME) \
$(MUPDF_EXE_OBJS) $(OBJDIR)\winres.RES $(LIBS)
$(MUPDF_DLL_OBJS) : $(OBJDIR)
#{$(BASEDIR)\mupdf}.cpp{$(OBJDIR)}.obj::
# $(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\draw}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\mupdf}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\stream}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\base}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\world}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\raster}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\apps\common}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<
{$(BASEDIR)\apps\windows}.c{$(OBJDIR)}.obj::
$(CC) $(CFLAGS) /Fo$(OBJDIR)\ /c $<

View file

@ -1,85 +0,0 @@
README for the Fitz distribution.
Fitz is a graphics library.
MuPDF is a PDF parsing and manipulation library.
Samus is a Metro parser.
FzView is a PDF and Metro viewer application.
For Windows, there is also a Mozilla plugin version of the viewer.
The Viewer has three ports: X11, Windows and Carbon.
The Carbon port is rotting, so don't bother trying it.
This code is under the same licensing scheme as Ghostscript.
AFPL and one year or major release later GPL.
Because there have been no major releases yet; AFPL it is.
PREREQUISITES
Before compiling Fitz you need to install thirdy party dependencies.
zlib
libjpeg
libpng
freetype2
expat
There are a few optional dependencies that you don't strictly need.
You will probably want the versions that Ghostscript maintains.
jbig2dec
jasper
Fitz uses the Perforce Jam build tool. You need the Perforce version 2.5
or later. Earlier versions (including the FTJam fork) have crippling bugs.
Boost Jam is not backwards compatible. If you do not have a compiled
binary for your system, you can find the Jam homepage here:
http://www.perforce.com/jam/jam.html
The build also uses 'xxd', a hexdump tool that ships with Vim.
Here's a copy of the source if it's not on your system:
http://ghostscript.com/~tor/download/xxd.c
I use Mingw and MSYS to compile for Windows. If you use anything
else, you are on your own.
COMPILING
If all of that is installed, compiling should be a cinch.
Issue the command 'jam' in the root of the Fitz directory.
Add a parameter '-sBUILD=release' or '-sBUILD=profile' to
build release or profile versions.
$ jam '-sBUILD=release'
If the build fails because it cannot find header files or libraries,
look first in Jamrules to see if there is anything wrong with the
search paths or compiler flags for your system.
To compile in the optional jbig2 and jpeg2000 support, you need
to add the following arguments to jam:
$ jam '-sHAVE_JBIG2DEC=yes' '-sHAVE_JASPER=yes'
To build the X11 version under MacOS X, add:
$ jam '-sHAVE_X11=yes'
INSTALLING
There is no install. The command "jam install" will copy the
compiled binaries (for the specified build -- debug, release or profile)
into a "dist/" directory.
There is no support for building a shared library.
REPORTING BUGS AND PROBLEMS
Send reports to tor@ghostscript.com.
If you are reporting a problem with PDF parsing,
please include the problematic file as an attachment.
-- tor

View file

@ -1,177 +0,0 @@
heh. bug in pdfselect on compressed object streams. gc takes forever, no objects remain...
lazy nametree
lazy pagetree
builtin standard cmap files (?)
put unicode strings in text object, not font (a la metro)
xml parser
unicode normaliser
path stroke/dash/flatten work on real path struct
turn into gel as second step after stroke/flatten
add intersector for metro union/xor/difference stuff
image rescale to exact size instead of by integer quantas
public / private api
fix the shading code:
3 levels of detail patch mesh (quad, patch, tensor)
subdivide to triangles on the fly
draw tris as before
reuse more code in the parsing
error cleanup
--- WORLD ---
the fitz world is:
the set of resources:
trees, fonts, images, shades, colorspaces
the list of pages:
references to tree resources
opaque / transparent / invisible ?
input device drivers create a fitz world from a document
readps -- use ghostscript
readpdf -- use mupdf
readmetro -- use samus
the mapping from file -> pages and resources
internal to the driver, nothing fitz cares or knows about
should be lazy -- loaded on an as-needed basis
should be reference counted -- can free and reload resources
minimal api (that works for *all* input drivers)
open(file)
close()
nextpage()
extended api (that may or may not work optimally)
countpages()
loadpage(number)
output drivers take a fitz world and produce whatever
raster
writeps
writepdf
writemetro
--- WORLD API ---
Fitz World APIs
Trees:
fz_tree
fz_node with subclasses
leafs:
fz_solidnode
fz_imagenode
fz_shadenode
fz_pathnode
fz_textnode
branches:
fz_transformnode
fz_overnode
fz_masknode
fz_blendnode # for pdf 1.4 and pcl rops
fz_linknode
fz_metanode
construction api
navigation api
Colorspaces:
fz_colorspace
fz_devicecolor (gray, rgb, cmyk)
fz_iccprofile (icc profile colorspace)
fz_separation (how do we do alternate tint functions?)
Images:
fz_image
fz_jpegimage # jpeg-compressed
fz_tileimage # 1,8,16 bit image chopped into tiles
...or...
fz_monoimage # 1-bit image
fz_byteimage # 8-bit image
fz_wordimage # 16-bit image
Shades:
fz_shade
mesh of quads, patches, tensors
Fonts:
fz_font
fz_fakefont # substitute fonts
fz_t3font # sub-trees define glyphs
fz_psfont # cff postscript font
fz_ttfont # truetype font
--- OLD ---
immediate plan:
* clean up and 'freeze' public api
* get font bbox from fontdescriptor if available
* refactor image loading
* refactor xref loading/repair
* restructure build.c and interpret.c (ftb vs csi)
* fix the colorspace/pattern/shading material mess
* font loading:
- configuration... where to find system files (asian font archive?)
- system fontfile + cmap store
- embedded fontfile store
- split type3 and ftfont malloc (dont waste t3 charprocs on ft fonts)
- make ftfontfile separate struct w/ refcounting
- refactor font loading more. simple/cid/type3 have too much in common.
* structure low/high level stuff
- rewrite outline parser
- implement comments
* clean high-level api
- go through spec and check all features!
- altivec optimize
transparency (v2)
- everything!
colorspace conversions (v2)
- fast color cubes
- proper colorspace conversions
- gamut compression
- extended render intents
image rendering (v2)
- tiles
- dct case
- better filter than box
- lazy decoding
rendering
- fix glyphcache evictlast
- bbox culling per glyph
- render cache (link-nodes and scaled images and colorspaced shades)
fz_optimizetree()
- error & memory
- concatenate chained transforms
- remove identity transforms
for filters:
validate ahxd pushback
go through eof responsibility
be more defensive of api user errors
jbig2 rewrite
dctencode params
dctdecode app marker
jpxd rewrite (or do special trick to load into image directly)

View file

@ -1,685 +0,0 @@
#include <fitz.h>
#include <mupdf.h>
#include "pdfapp.h"
void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage);
void pdfapp_warn(pdfapp_t *app, const char *fmt, ...)
{
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
winwarn(app, buf);
}
void pdfapp_error(pdfapp_t *app, fz_error *error)
{
winerror(app, error->msg);
}
char *pdfapp_usage(pdfapp_t *app)
{
return
" l <\t\t-- rotate left\n"
" r >\t\t-- rotate right\n"
" u up\t\t-- scroll up\n"
" d down\t-- scroll down\n"
" = +\t\t-- zoom in\n"
" -\t\t-- zoom out\n"
" w\t\t-- shrinkwrap\n"
"\n"
" n pgdn space\t-- next page\n"
" b pgup back\t-- previous page\n"
" right\t\t-- next page\n"
" left\t\t-- previous page\n"
" N F\t\t-- next 10\n"
" B\t\t-- back 10\n"
" m\t\t-- mark page for snap back\n"
" t\t\t-- pop back to last mark\n"
" 123g\t\t-- go to page\n"
"\n"
" left drag to pan, right drag to copy text\n";
}
void pdfapp_init(pdfapp_t *app)
{
fz_error *error;
memset(app, 0, sizeof(pdfapp_t));
error = fz_newrenderer(&app->rast, pdf_devicergb, 0, 1024 * 512);
if (error)
pdfapp_error(app, error);
app->scrw = 640;
app->scrh = 480;
}
void pdfapp_open(pdfapp_t *app, char *filename)
{
fz_error *error;
fz_obj *obj;
char *password = "";
/*
* Open PDF and load xref table
*/
app->filename = filename;
error = pdf_newxref(&app->xref);
if (error)
pdfapp_error(app, error);
error = pdf_loadxref(app->xref, filename);
if (error)
{
if (!strncmp(error->msg, "ioerror", 7))
pdfapp_error(app, error);
pdfapp_warn(app,
"There was a problem with file \"%s\".\n"
"It may be corrupted, or generated by broken software.\n\n"
"%s\n\nTrying to continue anyway...",
filename, error->msg);
error = pdf_repairxref(app->xref, filename);
if (error)
pdfapp_error(app, error);
}
/*
* Handle encrypted PDF files
*/
error = pdf_decryptxref(app->xref);
if (error)
pdfapp_error(app, error);
if (app->xref->crypt)
{
error = pdf_setpassword(app->xref->crypt, password);
while (error)
{
fz_droperror(error);
password = winpassword(app, filename);
if (!password)
exit(1);
error = pdf_setpassword(app->xref->crypt, password);
if (error)
pdfapp_warn(app, "Invalid password.");
}
}
/*
* Load page tree
*/
error = pdf_loadpagetree(&app->pages, app->xref);
if (error)
pdfapp_error(app, error);
/*
* Load meta information
* TODO: move this into mupdf library
*/
obj = fz_dictgets(app->xref->trailer, "Root");
if (!obj)
pdfapp_error(app, fz_throw("syntaxerror: missing Root object"));
error = pdf_loadindirect(&app->xref->root, app->xref, obj);
if (error)
pdfapp_error(app, error);
obj = fz_dictgets(app->xref->trailer, "Info");
if (obj)
{
error = pdf_loadindirect(&app->xref->info, app->xref, obj);
if (error)
pdfapp_error(app, error);
}
error = pdf_loadnametrees(app->xref);
if (error)
pdfapp_error(app, error);
error = pdf_loadoutline(&app->outline, app->xref);
if (error)
pdfapp_error(app, error);
app->doctitle = filename;
if (strrchr(app->doctitle, '\\'))
app->doctitle = strrchr(app->doctitle, '\\') + 1;
if (strrchr(app->doctitle, '/'))
app->doctitle = strrchr(app->doctitle, '/') + 1;
if (app->xref->info)
{
obj = fz_dictgets(app->xref->info, "Title");
if (obj)
{
error = pdf_toutf8(&app->doctitle, obj);
if (error)
pdfapp_error(app, error);
}
}
/*
* Start at first page
*/
app->shrinkwrap = 1;
if (app->pageno < 1)
app->pageno = 1;
if (app->zoom <= 0.0)
app->zoom = 1.0;
app->rotate = 0;
app->panx = 0;
app->pany = 0;
pdfapp_showpage(app, 1, 1);
}
void pdfapp_close(pdfapp_t *app)
{
if (app->pages)
pdf_droppagetree(app->pages);
app->pages = nil;
if (app->page)
pdf_droppage(app->page);
app->page = nil;
if (app->image)
fz_droppixmap(app->image);
app->image = nil;
if (app->outline)
pdf_dropoutline(app->outline);
app->outline = nil;
if (app->xref->store)
pdf_dropstore(app->xref->store);
app->xref->store = nil;
pdf_closexref(app->xref);
app->xref = nil;
}
fz_matrix pdfapp_viewctm(pdfapp_t *app)
{
fz_matrix ctm;
ctm = fz_identity();
ctm = fz_concat(ctm, fz_translate(0, -app->page->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(app->zoom, -app->zoom));
ctm = fz_concat(ctm, fz_rotate(app->rotate + app->page->rotate));
return ctm;
}
void pdfapp_panview(pdfapp_t *app, int newx, int newy)
{
if (newx > 0)
newx = 0;
if (newy > 0)
newy = 0;
if (newx + app->image->w < app->winw)
newx = app->winw - app->image->w;
if (newy + app->image->h < app->winh)
newy = app->winh - app->image->h;
if (app->winw >= app->image->w)
newx = (app->winw - app->image->w) / 2;
if (app->winh >= app->image->h)
newy = (app->winh - app->image->h) / 2;
if (newx != app->panx || newy != app->pany)
winrepaint(app);
app->panx = newx;
app->pany = newy;
}
void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
{
char buf[256];
fz_error *error;
fz_matrix ctm;
fz_rect bbox;
fz_obj *obj;
if (loadpage)
{
wincursor(app, WAIT);
if (app->page)
pdf_droppage(app->page);
app->page = nil;
obj = pdf_getpageobject(app->pages, app->pageno - 1);
error = pdf_loadpage(&app->page, app->xref, obj);
if (error)
pdfapp_error(app, error);
sprintf(buf, "%s - %d/%d", app->doctitle,
app->pageno, pdf_getpagecount(app->pages));
wintitle(app, buf);
}
if (drawpage)
{
wincursor(app, WAIT);
if (app->image)
fz_droppixmap(app->image);
app->image = nil;
ctm = pdfapp_viewctm(app);
bbox = fz_transformaabb(ctm, app->page->mediabox);
error = fz_rendertree(&app->image, app->rast, app->page->tree,
ctm, fz_roundrect(bbox), 1);
if (error)
pdfapp_error(app, error);
winconvert(app, app->image);
}
pdfapp_panview(app, app->panx, app->pany);
if (app->shrinkwrap)
{
int w = app->image->w;
int h = app->image->h;
if (app->winw == w)
app->panx = 0;
if (app->winh == h)
app->pany = 0;
if (w > app->scrw * 90 / 100)
w = app->scrw * 90 / 100;
if (h > app->scrh * 90 / 100)
h = app->scrh * 90 / 100;
if (w != app->winw || h != app->winh)
winresize(app, w, h);
}
winrepaint(app);
wincursor(app, ARROW);
}
void pdfapp_gotouri(pdfapp_t *app, fz_obj *uri)
{
char buf[2048];
memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri));
buf[fz_tostrlen(uri)] = 0;
winopenuri(app, buf);
}
void pdfapp_gotopage(pdfapp_t *app, fz_obj *obj)
{
int oid = fz_tonum(obj);
int i;
for (i = 0; i < pdf_getpagecount(app->pages); i++)
{
if (fz_tonum(app->pages->pref[i]) == oid)
{
if (app->histlen + 1 == 256)
{
memmove(app->hist, app->hist + 1, sizeof(int) * 255);
app->histlen --;
}
app->hist[app->histlen++] = app->pageno;
app->pageno = i + 1;
pdfapp_showpage(app, 1, 1);
return;
}
}
}
void pdfapp_onresize(pdfapp_t *app, int w, int h)
{
if (app->winw != w || app->winh != h)
{
app->winw = w;
app->winh = h;
pdfapp_panview(app, app->panx, app->pany);
winrepaint(app);
}
}
void pdfapp_onkey(pdfapp_t *app, int c)
{
int oldpage = app->pageno;
int panto = 0; /* 0 = top, 1 = bottom, 2 = leave alone */
/*
* Save numbers typed for later
*/
if (c >= '0' && c <= '9')
app->number[app->numberlen++] = c;
else
if (c != 'g' && c != 'G')
app->numberlen = 0;
switch (c)
{
/*
* Zoom and rotate
*/
case '+': case '=':
app->zoom += 0.1;
if (app->zoom > 3.0)
app->zoom = 3.0;
pdfapp_showpage(app, 0, 1);
break;
case '-':
app->zoom -= 0.1;
if (app->zoom < 0.1)
app->zoom = 0.1;
pdfapp_showpage(app, 0, 1);
break;
case 'l': case '<':
app->rotate -= 90;
pdfapp_showpage(app, 0, 1);
break;
case 'r': case '>':
app->rotate += 90;
pdfapp_showpage(app, 0, 1);
break;
case 'a':
app->rotate -= 15;
pdfapp_showpage(app, 0, 1);
break;
case 's':
app->rotate += 15;
pdfapp_showpage(app, 0, 1);
break;
/*
* Pan view, but dont need to repaint image
*/
case 'w':
app->shrinkwrap = 1;
app->panx = app->pany = 0;
pdfapp_showpage(app, 0, 0);
break;
case 'd':
app->pany -= app->image->h / 10;
pdfapp_showpage(app, 0, 0);
break;
case 'u':
app->pany += app->image->h / 10;
pdfapp_showpage(app, 0, 0);
break;
case ',':
app->panx += app->image->w / 10;
pdfapp_showpage(app, 0, 0);
break;
case '.':
app->panx -= app->image->w / 10;
pdfapp_showpage(app, 0, 0);
break;
/*
* Page navigation
*/
case 'g':
case '\n':
case '\r':
if (app->numberlen > 0)
{
app->number[app->numberlen] = '\0';
app->pageno = atoi(app->number);
app->numberlen = 0;
}
break;
case 'G':
app->pageno = pdf_getpagecount(app->pages);
break;
case 'm':
if (app->histlen + 1 == 256)
{
memmove(app->hist, app->hist + 1, sizeof(int) * 255);
app->histlen --;
}
app->hist[app->histlen++] = app->pageno;
break;
case 't':
if (app->histlen > 0)
app->pageno = app->hist[--app->histlen];
break;
/*
* Back and forth ...
*/
case 'p':
panto = 2;
app->pageno--;
break;
case 'b': case '\b':
panto = 1;
app->pageno--;
break;
case 'n':
panto = 2;
case 'f': case ' ':
app->pageno++;
break;
case 'B':
app->pageno -= 10;
break;
case 'F':
app->pageno += 10;
break;
}
if (app->pageno < 1)
app->pageno = 1;
if (app->pageno > pdf_getpagecount(app->pages))
app->pageno = pdf_getpagecount(app->pages);
if (app->pageno != oldpage)
{
switch (panto)
{
case 0: app->pany = 0; break;
case 1: app->pany = -2000; break;
case 2: break;
}
pdfapp_showpage(app, 1, 1);
}
}
void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state)
{
pdf_link *link;
fz_matrix ctm;
fz_point p;
p.x = x - app->panx + app->image->x;
p.y = y - app->pany + app->image->y;
ctm = pdfapp_viewctm(app);
ctm = fz_invertmatrix(ctm);
p = fz_transformpoint(ctm, p);
for (link = app->page->links; link; link = link->next)
{
if (p.x >= link->rect.x0 && p.x <= link->rect.x1)
if (p.y >= link->rect.y0 && p.y <= link->rect.y1)
break;
}
if (link)
{
wincursor(app, HAND);
if (btn == 1 && state == 1)
{
if (fz_isstring(link->dest))
pdfapp_gotouri(app, link->dest);
if (fz_isindirect(link->dest))
pdfapp_gotopage(app, link->dest);
return;
}
}
else
{
wincursor(app, ARROW);
}
if (state == 1)
{
if (btn == 1 && !app->iscopying)
{
app->ispanning = 1;
app->selx = x;
app->sely = y;
}
if (btn == 3 && !app->ispanning)
{
app->iscopying = 1;
app->selx = x;
app->sely = y;
app->selr.x0 = x;
app->selr.x1 = x;
app->selr.y0 = y;
app->selr.y1 = y;
}
if (btn == 4 || btn == 5) /* scroll wheel */
{
int dir = btn == 4 ? 1 : -1;
app->ispanning = app->iscopying = 0;
if (modifiers & (1<<2))
{
/* zoom in/out if ctrl is pressed */
app->zoom += 0.1 * dir;
if (app->zoom > 3.0)
app->zoom = 3.0;
if (app->zoom < 0.1)
app->zoom = 0.1;
pdfapp_showpage(app, 0, 1);
}
else
{
/* scroll up/down, or left/right if
shift is pressed */
int isx = (modifiers & (1<<0));
int xstep = isx ? 20 * dir : 0;
int ystep = !isx ? 20 * dir : 0;
pdfapp_panview(app, app->panx + xstep, app->pany + ystep);
}
}
}
else if (state == -1)
{
if (app->iscopying)
{
app->iscopying = 0;
app->selr.x0 = MIN(app->selx, x);
app->selr.x1 = MAX(app->selx, x);
app->selr.y0 = MIN(app->sely, y);
app->selr.y1 = MAX(app->sely, y);
winrepaint(app);
if (app->selr.x0 < app->selr.x1 && app->selr.y0 < app->selr.y1)
windocopy(app);
}
if (app->ispanning)
app->ispanning = 0;
}
else if (app->ispanning)
{
int newx = app->panx + x - app->selx;
int newy = app->pany + y - app->sely;
pdfapp_panview(app, newx, newy);
app->selx = x;
app->sely = y;
}
else if (app->iscopying)
{
app->selr.x0 = MIN(app->selx, x);
app->selr.x1 = MAX(app->selx, x);
app->selr.y0 = MIN(app->sely, y);
app->selr.y1 = MAX(app->sely, y);
winrepaint(app);
}
}
void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
{
fz_error *error;
pdf_textline *line, *ln;
int y, c;
int i, p;
int bx0, bx1, by0, by1;
int x0 = app->image->x + app->selr.x0 - app->panx;
int x1 = app->image->x + app->selr.x1 - app->panx;
int y0 = app->image->y + app->selr.y0 - app->pany;
int y1 = app->image->y + app->selr.y1 - app->pany;
error = pdf_loadtextfromtree(&line, app->page->tree, pdfapp_viewctm(app));
if (error)
pdfapp_error(app, error);
p = 0;
for (ln = line; ln; ln = ln->next)
{
y = y0 - 1;
for (i = 0; i < ln->len; i++)
{
bx0 = ln->text[i].bbox.x0;
bx1 = ln->text[i].bbox.x1;
by0 = ln->text[i].bbox.y0;
by1 = ln->text[i].bbox.y1;
c = ln->text[i].c;
if (c < 32)
c = '?';
if (bx1 >= x0 && bx0 <= x1 && by1 >= y0 && by0 <= y1)
if (p < ucslen - 1)
ucsbuf[p++] = c;
}
if (by1 >= y0 && by0 <= y1)
{
#ifdef WIN32
if (p < ucslen - 1)
ucsbuf[p++] = '\r';
#endif
if (p < ucslen - 1)
ucsbuf[p++] = '\n';
}
}
ucsbuf[p] = 0;
pdf_droptextline(line);
}

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>ghostpdf</string>
<key>CFBundleIconFile</key>
<string>macpdf.icns</string>
<key>CFBundleIdentifier</key>
<string>com.artofcode.GhostPDF</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.1</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdf</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>macpdf.icns</string>
<key>CFBundleTypeName</key>
<string>PDF Document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
</dict>
</plist>

View file

@ -1,7 +0,0 @@
/* Localized versions of Info.plist keys */
CFBundleName = "GhostPDF";
CFBundleShortVersionString = "GhostPDF version 1.0.0";
CFBundleGetInfoString = "Copyright (C) 2005 artofcode LLC.";
NSHumanReadableCopyright = "Copyright (C) 2005 artofcode LLC.";

View file

@ -1,4 +0,0 @@
{
IBClasses = ();
IBVersion = 1;
}

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>54 19 356 240 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>15 273 236 44 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>349.0</string>
<key>IBOpenObjects</key>
<array>
<integer>166</integer>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>7W98</string>
<key>targetFramework</key>
<string>IBCarbonFramework</string>
</dict>
</plist>

View file

@ -1,516 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<object class="NSIBObjectData">
<string name="targetFramework">IBCarbonFramework</string>
<object name="rootObject" class="NSCustomObject" id="1">
<string name="customClass">NSApplication</string>
</object>
<array count="58" name="allObjects">
<object class="IBCarbonMenu" id="29">
<string name="title">GhostPDF</string>
<array count="4" name="items">
<object class="IBCarbonMenuItem" id="185">
<string name="title">MuView</string>
<object name="submenu" class="IBCarbonMenu" id="184">
<string name="title">MuView</string>
<array count="1" name="items">
<object class="IBCarbonMenuItem" id="187">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">About MuView</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">abou</ostype>
</object>
</array>
<string name="name">_NSAppleMenu</string>
</object>
</object>
<object class="IBCarbonMenuItem" id="127">
<string name="title">File</string>
<object name="submenu" class="IBCarbonMenu" id="131">
<string name="title">File</string>
<array count="10" name="items">
<object class="IBCarbonMenuItem" id="139">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">New</string>
<string name="keyEquivalent">n</string>
<ostype name="command">new </ostype>
</object>
<object class="IBCarbonMenuItem" id="134">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Open…</string>
<string name="keyEquivalent">o</string>
<ostype name="command">open</ostype>
</object>
<object class="IBCarbonMenuItem" id="133">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="130">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Close</string>
<string name="keyEquivalent">w</string>
<ostype name="command">clos</ostype>
</object>
<object class="IBCarbonMenuItem" id="138">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Save</string>
<string name="keyEquivalent">s</string>
<ostype name="command">save</ostype>
</object>
<object class="IBCarbonMenuItem" id="137">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Save As…</string>
<string name="keyEquivalent">S</string>
<ostype name="command">svas</ostype>
</object>
<object class="IBCarbonMenuItem" id="132">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Revert</string>
<string name="keyEquivalent">r</string>
<ostype name="command">rvrt</ostype>
</object>
<object class="IBCarbonMenuItem" id="128">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="135">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Page Setup…</string>
<string name="keyEquivalent">P</string>
<ostype name="command">page</ostype>
</object>
<object class="IBCarbonMenuItem" id="136">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Print…</string>
<string name="keyEquivalent">p</string>
<ostype name="command">prnt</ostype>
</object>
</array>
</object>
</object>
<object class="IBCarbonMenuItem" id="152">
<string name="title">Edit</string>
<object name="submenu" class="IBCarbonMenu" id="147">
<string name="title">Edit</string>
<array count="10" name="items">
<object class="IBCarbonMenuItem" id="141">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Undo</string>
<string name="keyEquivalent">z</string>
<ostype name="command">undo</ostype>
</object>
<object class="IBCarbonMenuItem" id="146">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Redo</string>
<string name="keyEquivalent">Z</string>
<ostype name="command">redo</ostype>
</object>
<object class="IBCarbonMenuItem" id="142">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="143">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Cut</string>
<string name="keyEquivalent">x</string>
<ostype name="command">cut </ostype>
</object>
<object class="IBCarbonMenuItem" id="149">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Copy</string>
<string name="keyEquivalent">c</string>
<ostype name="command">copy</ostype>
</object>
<object class="IBCarbonMenuItem" id="144">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Paste</string>
<string name="keyEquivalent">v</string>
<ostype name="command">past</ostype>
</object>
<object class="IBCarbonMenuItem" id="151">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Delete</string>
<ostype name="command">clea</ostype>
</object>
<object class="IBCarbonMenuItem" id="148">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Select All</string>
<string name="keyEquivalent">a</string>
<ostype name="command">sall</ostype>
</object>
<object class="IBCarbonMenuItem" id="192">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="191">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Special Characters…</string>
<ostype name="command">chrp</ostype>
</object>
</array>
</object>
</object>
<object class="IBCarbonMenuItem" id="153">
<string name="title">Window</string>
<object name="submenu" class="IBCarbonMenu" id="154">
<string name="title">Window</string>
<array count="6" name="items">
<object class="IBCarbonMenuItem" id="155">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Minimize Window</string>
<string name="keyEquivalent">m</string>
<ostype name="command">mini</ostype>
</object>
<object class="IBCarbonMenuItem" id="188">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Minimize All Windows</string>
<string name="keyEquivalent">m</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">mina</ostype>
</object>
<object class="IBCarbonMenuItem" id="190">
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Zoom</string>
<ostype name="command">zoom</ostype>
</object>
<object class="IBCarbonMenuItem" id="156">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="157">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Bring All to Front</string>
<ostype name="command">bfrt</ostype>
</object>
<object class="IBCarbonMenuItem" id="189">
<boolean name="dynamic">TRUE</boolean>
<boolean name="updateSingleItem">TRUE</boolean>
<string name="title">Arrange in Front</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">frnt</ostype>
</object>
</array>
<string name="name">_NSWindowsMenu</string>
</object>
</object>
</array>
<string name="name">_NSMainMenu</string>
</object>
<reference idRef="127"/>
<reference idRef="128"/>
<reference idRef="130"/>
<reference idRef="131"/>
<reference idRef="132"/>
<reference idRef="133"/>
<reference idRef="134"/>
<reference idRef="135"/>
<reference idRef="136"/>
<reference idRef="137"/>
<reference idRef="138"/>
<reference idRef="139"/>
<reference idRef="141"/>
<reference idRef="142"/>
<reference idRef="143"/>
<reference idRef="144"/>
<reference idRef="146"/>
<reference idRef="147"/>
<reference idRef="148"/>
<reference idRef="149"/>
<reference idRef="151"/>
<reference idRef="152"/>
<reference idRef="153"/>
<reference idRef="154"/>
<reference idRef="155"/>
<reference idRef="156"/>
<reference idRef="157"/>
<object class="IBCarbonWindow" id="166">
<string name="windowRect">56 24 553 587 </string>
<string name="title">Window</string>
<object name="rootControl" class="IBCarbonRootControl" id="167">
<string name="bounds">0 0 497 563 </string>
<string name="viewFrame">0 0 563 497 </string>
<array count="13" name="subviews">
<object class="IBCarbonScrollBar" id="197">
<string name="bounds">482 248 497 549 </string>
<string name="viewFrame">248 482 301 15 </string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingLeftKind">1</int>
<int name="bindingBottomKind">2</int>
<int name="bindingRightKind">2</int>
</object>
</object>
<object class="IBCarbonScrollBar" id="198">
<string name="bounds">-1 548 483 563 </string>
<string name="viewFrame">548 -1 15 484 </string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingTopKind">1</int>
<int name="bindingBottomKind">2</int>
<int name="bindingRightKind">2</int>
</object>
</object>
<object class="IBCarbonBevelButton" id="201">
<string name="bounds">482 23 498 47 </string>
<string name="viewFrame">23 482 24 16 </string>
<string name="title">&lt;</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingLeftKind">1</int>
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="204">
<string name="bounds">482 46 498 70 </string>
<string name="viewFrame">46 482 24 16 </string>
<string name="title">&gt;</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="205">
<string name="bounds">482 92 498 112 </string>
<string name="viewFrame">92 482 20 16 </string>
<string name="title">(</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="206">
<string name="bounds">482 111 498 131 </string>
<string name="viewFrame">111 482 20 16 </string>
<string name="title">)</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonEditText" id="209">
<string name="bounds">485 199 495 237 </string>
<string name="viewFrame">199 485 38 10 </string>
<boolean name="small">TRUE</boolean>
<int name="controlSize">3</int>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<boolean name="isUnicode">TRUE</boolean>
</object>
<object class="IBCarbonBevelButton" id="210">
<string name="bounds">482 0 498 24 </string>
<string name="viewFrame">0 482 24 16 </string>
<string name="title">&lt;&lt;</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingLeftKind">1</int>
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="211">
<string name="bounds">482 69 498 93 </string>
<string name="viewFrame">69 482 24 16 </string>
<string name="title">&gt;&gt;</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="227">
<string name="bounds">482 168 498 188 </string>
<string name="viewFrame">168 482 20 16 </string>
<string name="title">+</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="228">
<string name="bounds">482 130 498 150 </string>
<string name="viewFrame">130 482 20 16 </string>
<string name="title">-</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonBevelButton" id="229">
<string name="bounds">482 149 498 169 </string>
<string name="viewFrame">149 482 20 16 </string>
<string name="title">%</string>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingBottomKind">2</int>
</object>
<int name="contentType">0</int>
<int name="textPlacement">3</int>
</object>
<object class="IBCarbonHIView" id="230">
<string name="bounds">0 0 484 549 </string>
<string name="viewFrame">0 0 549 484 </string>
<ostype name="controlSignature">Poof</ostype>
<int name="controlID">666</int>
<object name="layoutInfo" class="IBCarbonHILayoutInfo">
<int name="bindingTopKind">1</int>
<int name="bindingLeftKind">1</int>
<int name="bindingBottomKind">2</int>
<int name="bindingRightKind">2</int>
</object>
<string name="classID">com.artofcode.ghostpdf.View</string>
</object>
</array>
</object>
<boolean name="receiveUpdates">FALSE</boolean>
<boolean name="liveResize">TRUE</boolean>
<boolean name="compositing">TRUE</boolean>
<boolean name="isConstrained">FALSE</boolean>
</object>
<reference idRef="167"/>
<reference idRef="184"/>
<reference idRef="185"/>
<reference idRef="187"/>
<reference idRef="188"/>
<reference idRef="189"/>
<reference idRef="190"/>
<reference idRef="191"/>
<reference idRef="192"/>
<reference idRef="197"/>
<reference idRef="198"/>
<reference idRef="201"/>
<reference idRef="204"/>
<reference idRef="205"/>
<reference idRef="206"/>
<reference idRef="209"/>
<reference idRef="210"/>
<reference idRef="211"/>
<reference idRef="227"/>
<reference idRef="228"/>
<reference idRef="229"/>
<reference idRef="230"/>
<object class="IBCarbonWindow" id="231">
<string name="windowRect">200 83 330 337 </string>
<string name="title">Password</string>
<object name="rootControl" class="IBCarbonRootControl" id="232">
<string name="bounds">0 0 130 254 </string>
<string name="viewFrame">0 0 254 130 </string>
<array count="5" name="subviews">
<object class="IBCarbonStaticText" id="233">
<string name="bounds">20 20 36 234 </string>
<string name="viewFrame">20 20 214 16 </string>
<string name="title">This document is encrypted.</string>
</object>
<object class="IBCarbonStaticText" id="234">
<string name="bounds">50 32 66 146 </string>
<string name="viewFrame">32 50 114 16 </string>
<string name="title">Password:</string>
</object>
<object class="IBCarbonEditText" id="235">
<string name="bounds">51 106 67 215 </string>
<string name="viewFrame">106 51 109 16 </string>
<boolean name="isPassword">TRUE</boolean>
<boolean name="isUnicode">TRUE</boolean>
<boolean name="isSingleLine">TRUE</boolean>
</object>
<object class="IBCarbonButton" id="237">
<string name="bounds">90 132 110 202 </string>
<string name="viewFrame">132 90 70 20 </string>
<string name="title">OK</string>
<int name="buttonType">1</int>
</object>
<object class="IBCarbonButton" id="238">
<string name="bounds">90 50 110 120 </string>
<string name="viewFrame">50 90 70 20 </string>
<string name="title">Cancel</string>
</object>
</array>
</object>
<boolean name="receiveUpdates">FALSE</boolean>
<boolean name="isResizable">FALSE</boolean>
<boolean name="liveResize">TRUE</boolean>
<boolean name="compositing">TRUE</boolean>
<int name="carbonWindowClass">11</int>
<boolean name="isConstrained">FALSE</boolean>
</object>
<reference idRef="232"/>
<reference idRef="233"/>
<reference idRef="234"/>
<reference idRef="235"/>
<reference idRef="237"/>
<reference idRef="238"/>
</array>
<array count="58" name="allParents">
<reference idRef="1"/>
<reference idRef="29"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="127"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="131"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="152"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="29"/>
<reference idRef="29"/>
<reference idRef="153"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="1"/>
<reference idRef="166"/>
<reference idRef="185"/>
<reference idRef="29"/>
<reference idRef="184"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="154"/>
<reference idRef="147"/>
<reference idRef="147"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="1"/>
<reference idRef="231"/>
<reference idRef="232"/>
<reference idRef="232"/>
<reference idRef="232"/>
<reference idRef="232"/>
<reference idRef="232"/>
</array>
<dictionary count="5" name="nameTable">
<string>Files Owner</string>
<reference idRef="1"/>
<string>MainWindow</string>
<reference idRef="166"/>
<string>MenuBar</string>
<reference idRef="29"/>
<string>PasswordWindow</string>
<reference idRef="231"/>
<string>View1</string>
<reference idRef="230"/>
</dictionary>
<unsigned_int name="nextObjectID">239</unsigned_int>
</object>

View file

@ -1,438 +0,0 @@
#include <Carbon/Carbon.h>
#include <fitz.h>
#include <mupdf.h>
#include "pdfapp.h"
#define gDefaultFilename "/Users/giles/projects/ghostscript/tiger.pdf"
#define kViewClassID CFSTR("com.artofcode.ghostpdf.View")
#define kViewPrivate 'MU_v'
/* the pdfapp abstraction currently uses magic callbacks, so we have
to use a a global state for our own data, or subclass pdfapp_t and
do a lot of casting */
/* pdfapp callbacks - error handling */
void winwarn(pdfapp_t *pdf, char *msg)
{
fprintf(stderr, "ghostpdf warning: %s\n", msg);
}
void winerror(pdfapp_t *pdf, char *msg)
{
fprintf(stderr, "ghostpdf error: %s\n", msg);
exit(1);
}
/* pdfapp callbacks - drawing */
void wintitle(pdfapp_t *pdf, char *title)
{
/* set new document title */
}
void winresize(pdfapp_t *pdf, int w, int h)
{
/* pdfapp as been asked to shrinkwrap the document image;
we're called to actually apply the new window size. */
}
void winconvert(pdfapp_t *pdf, fz_pixmap *image)
{
/* notification that page drawing is complete */
/* do nothing */
}
void winrepaint(pdfapp_t *pdf)
{
/* image needs repainting */
HIViewSetNeedsDisplay((HIViewRef)pdf->userdata, true);
}
char* winpassword(pdfapp_t *pdf, char *filename)
{
/* prompt user for document password */
return NULL;
}
void winopenuri(pdfapp_t *pdf, char *s)
{
/* user clicked on an external uri */
/* todo: launch browser and/or open a new window if it's a PDF */
}
void wincursor(pdfapp_t *pdf, int curs)
{
/* cursor status change notification */
}
void windocopy(pdfapp_t *pdf)
{
/* user selected some text; copy it to the clipboard */
}
static OSStatus
view_construct(EventRef inEvent)
{
OSStatus err;
pdfapp_t *pdf;
pdf = (pdfapp_t *)malloc(sizeof(pdfapp_t));
require_action(pdf != NULL, CantMalloc, err = memFullErr);
pdfapp_init(pdf);
err = GetEventParameter(inEvent, kEventParamHIObjectInstance,
typeHIObjectRef, NULL, sizeof(HIObjectRef), NULL,
(HIObjectRef *)&pdf->userdata);
require_noerr(err, ParameterMissing);
err = SetEventParameter(inEvent, kEventParamHIObjectInstance,
typeVoidPtr, sizeof(pdfapp_t *), &pdf);
ParameterMissing:
if (err != noErr)
free(pdf);
CantMalloc:
return err;
}
static OSStatus
view_destruct(EventRef inEvent, pdfapp_t *pdf)
{
pdfapp_close(pdf);
free(pdf);
return noErr;
}
static OSStatus
view_initialize(EventHandlerCallRef inCallRef, EventRef inEvent,
pdfapp_t *pdf)
{
OSStatus err;
HIRect bounds;
HIViewRef view = (HIViewRef)pdf->userdata;
err = CallNextEventHandler(inCallRef, inEvent);
require_noerr(err, TroubleInSuperClass);
HIViewGetBounds (view, &bounds);
pdf->scrw = bounds.size.width;
pdf->scrh = bounds.size.height;
pdfapp_open(pdf, gDefaultFilename);
TroubleInSuperClass:
return err;
}
static void
cgcontext_set_rgba(CGContextRef ctx, unsigned int rgba)
{
const double norm = 1.0 / 255;
CGContextSetRGBFillColor(ctx,
((rgba >> 24) & 0xff) * norm,
((rgba >> 16) & 0xff) * norm,
((rgba >> 8) & 0xff) * norm,
(rgba & 0xff) * norm);
}
static void
draw_rect(CGContextRef ctx, double x0, double y0, double x1, double y1,
unsigned int rgba)
{
HIRect rect;
cgcontext_set_rgba(ctx, rgba);
rect.origin.x = x0;
rect.origin.y = y0;
rect.size.width = x1 - x0;
rect.size.height = y1 - y0;
CGContextFillRect(ctx, rect);
}
static OSStatus
view_draw(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
CGContextRef gc;
CGDataProviderRef provider;
CGImageRef image;
CGColorSpaceRef colorspace;
CGRect rect;
err = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef,
NULL, sizeof(CGContextRef), NULL, &gc);
require_noerr(err, cleanup);
colorspace = CGColorSpaceCreateDeviceRGB();
provider = CGDataProviderCreateWithData(NULL, pdf->image->samples,
pdf->image->w * pdf->image->h * 4,
NULL);
image = CGImageCreate(pdf->image->w, pdf->image->h,
8, 32, pdf->image->w * 4,
colorspace, kCGImageAlphaNoneSkipFirst, provider,
NULL, 0, kCGRenderingIntentDefault);
rect.origin.x = 0;
rect.origin.y = 0;
rect.size.width = pdf->image->w;
rect.size.height = pdf->image->h;
HIViewDrawCGImage(gc, &rect, image);
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
cleanup:
return err;
}
static OSStatus
view_get_data(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
OSType tag;
Ptr ptr;
Size outSize;
/* Probably could use a bit more error checking here, for type
and size match. Also, just returning a viewctx seems a
little hacky. */
err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration,
NULL, sizeof(OSType), NULL, &tag);
require_noerr(err, ParameterMissing);
err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr,
NULL, sizeof(Ptr), NULL, &ptr);
if (tag == kViewPrivate) {
*((pdfapp_t **)ptr) = pdf;
outSize = sizeof(pdfapp_t *);
} else
err = errDataNotSupported;
if (err == noErr)
err = SetEventParameter(inEvent, kEventParamControlDataBufferSize, typeLongInteger,
sizeof(Size), &outSize);
ParameterMissing:
return err;
}
static OSStatus
view_set_data(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
Ptr ptr;
OSType tag;
err = GetEventParameter(inEvent, kEventParamControlDataTag, typeEnumeration,
NULL, sizeof(OSType), NULL, &tag);
require_noerr(err, ParameterMissing);
err = GetEventParameter(inEvent, kEventParamControlDataBuffer, typePtr,
NULL, sizeof(Ptr), NULL, &ptr);
require_noerr(err, ParameterMissing);
/* we think we don't use this */
err = errDataNotSupported;
ParameterMissing:
return err;
}
static OSStatus
view_hittest(EventRef inEvent, pdfapp_t *pdf)
{
OSStatus err;
HIPoint where;
HIRect bounds;
ControlPartCode part;
err = GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint,
NULL, sizeof(HIPoint), NULL, &where);
require_noerr(err, ParameterMissing);
err = HIViewGetBounds(pdf->userdata, &bounds);
require_noerr(err, ParameterMissing);
if (CGRectContainsPoint(bounds, where))
part = 1;
else
part = kControlNoPart;
err = SetEventParameter(inEvent, kEventParamControlPart,
typeControlPartCode, sizeof(ControlPartCode),
&part);
printf("hittest %g, %g!\n", where.x, where.y);
ParameterMissing:
return err;
}
pascal OSStatus
view_handler(EventHandlerCallRef inCallRef,
EventRef inEvent,
void* inUserData )
{
OSStatus err = eventNotHandledErr;
UInt32 eventClass = GetEventClass(inEvent);
UInt32 eventKind = GetEventKind(inEvent);
pdfapp_t *pdf = (pdfapp_t *)inUserData;
switch (eventClass) {
case kEventClassHIObject:
switch (eventKind) {
case kEventHIObjectConstruct:
err = view_construct(inEvent);
break;
case kEventHIObjectInitialize:
err = view_initialize(inCallRef, inEvent, pdf);
break;
case kEventHIObjectDestruct:
err = view_destruct(inEvent, pdf);
break;
}
break;
case kEventClassControl:
switch (eventKind) {
case kEventControlInitialize:
err = noErr;
break;
case kEventControlDraw:
err = view_draw(inEvent, pdf);
break;
case kEventControlGetData:
err = view_get_data(inEvent, pdf);
break;
case kEventControlSetData:
err = view_set_data(inEvent, pdf);
break;
case kEventControlHitTest:
err = view_hittest(inEvent, pdf);
break;
/*...*/
}
break;
}
return err;
}
OSStatus
view_register(void)
{
OSStatus err = noErr;
static HIObjectClassRef view_ClassRef = NULL;
if (view_ClassRef == NULL) {
EventTypeSpec eventList[] = {
{ kEventClassHIObject, kEventHIObjectConstruct },
{ kEventClassHIObject, kEventHIObjectInitialize },
{ kEventClassHIObject, kEventHIObjectDestruct },
{ kEventClassControl, kEventControlActivate },
{ kEventClassControl, kEventControlDeactivate },
{ kEventClassControl, kEventControlDraw },
{ kEventClassControl, kEventControlHiliteChanged },
{ kEventClassControl, kEventControlHitTest },
{ kEventClassControl, kEventControlInitialize },
{ kEventClassControl, kEventControlGetData },
{ kEventClassControl, kEventControlSetData },
};
err = HIObjectRegisterSubclass(kViewClassID,
kHIViewClassID,
NULL,
view_handler,
GetEventTypeCount(eventList),
eventList,
NULL,
&view_ClassRef);
}
return err;
}
OSStatus view_create(
WindowRef inWindow,
const HIRect* inBounds,
HIViewRef* outView)
{
OSStatus err;
EventRef event;
err = view_register();
require_noerr(err, CantRegister);
err = CreateEvent(NULL, kEventClassHIObject, kEventHIObjectInitialize,
GetCurrentEventTime(), 0, &event);
require_noerr(err, CantCreateEvent);
if (inBounds != NULL) {
err = SetEventParameter(event, 'Boun', typeHIRect, sizeof(HIRect),
inBounds);
require_noerr(err, CantSetParameter);
}
err = HIObjectCreate(kViewClassID, event, (HIObjectRef*)outView);
require_noerr(err, CantCreate);
if (inWindow != NULL) {
HIViewRef root;
err = GetRootControl(inWindow, &root);
require_noerr(err, CantGetRootView);
err = HIViewAddSubview(root, *outView);
}
CantCreate:
CantGetRootView:
CantSetParameter:
CantCreateEvent:
ReleaseEvent(event);
CantRegister:
return err;
}
int main(int argc, char *argv[])
{
IBNibRef nibRef;
OSStatus err;
WindowRef window;
pdfapp_t pdf;
fz_cpudetect();
fz_accelerate();
err = view_register();
require_noerr(err, CantRegisterView);
err = CreateNibReference(CFSTR("main"), &nibRef);
printf("err = %d\n", (int)err);
require_noerr(err, CantGetNibRef);
err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr(err, CantSetMenuBar);
err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
require_noerr(err, CantCreateWindow);
//openpdf(window, gDefaultFilename);
DisposeNibReference(nibRef);
pdfapp_init(&pdf);
pdfapp_open(&pdf, gDefaultFilename);
ShowWindow(window);
RunApplicationEventLoop();
pdfapp_close(&pdf);
CantGetNibRef:
CantSetMenuBar:
CantCreateWindow:
CantRegisterView:
return err;
}

View file

@ -1,5 +0,0 @@
/* dummy jri */
#define jref void*
#define JRIEnv void
#define JRIGlobalRef void*
#define JRI_NewGlobalRef(e,c) 0

View file

@ -1,889 +0,0 @@
#include "fitz.h"
#include "mupdf.h"
#include <windows.h>
#include <windowsx.h>
#include "npapi.h"
#include "npupp.h"
#define PAD 5
#define MSG(s) MessageBox(0,s,"MuPDF Debug",MB_OK)
typedef struct pdfmoz_s pdfmoz_t;
typedef struct page_s page_t;
struct page_s
{
fz_obj *ref;
fz_obj *obj;
pdf_page *page;
fz_pixmap *image;
int w, h; /* page size in units */
int px; /* pixel height */
};
struct pdfmoz_s
{
NPP inst;
HWND hwnd;
HWND sbar;
WNDPROC winproc;
HCURSOR arrow, hand, wait;
BITMAPINFO *dibinf;
HBRUSH graybrush;
int scrollpage; /* scrollbar -> page (n) */
int scrollyofs; /* scrollbar -> page offset in pixels */
int pagecount;
page_t *pages;
char *filename;
char *doctitle;
pdf_xref *xref;
fz_renderer *rast;
char error[1024]; /* empty if no error has occured */
};
void pdfmoz_warn(pdfmoz_t *moz, const char *fmt, ...)
{
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
strcpy(moz->error, buf);
InvalidateRect(moz->hwnd, NULL, FALSE);
NPN_Status(moz->inst, moz->error);
}
void pdfmoz_error(pdfmoz_t *moz, fz_error *error)
{
strcpy(moz->error, error->msg);
InvalidateRect(moz->hwnd, NULL, FALSE);
NPN_Status(moz->inst, moz->error);
}
void pdfmoz_open(pdfmoz_t *moz, char *filename)
{
SCROLLINFO si;
fz_error *error;
fz_obj *obj;
char *password = "";
pdf_pagetree *pages;
fz_irect bbox;
int rot;
int i;
strcpy(moz->error, "");
error = fz_newrenderer(&moz->rast, pdf_devicergb, 0, 1024 * 512);
if (error)
pdfmoz_error(moz, error);
/*
* Open PDF and load xref table
*/
moz->filename = filename;
error = pdf_newxref(&moz->xref);
if (error)
pdfmoz_error(moz, error);
error = pdf_loadxref(moz->xref, filename);
if (error)
{
if (!strncmp(error->msg, "ioerror", 7))
pdfmoz_error(moz, error);
error = pdf_repairxref(moz->xref, filename);
if (error)
pdfmoz_error(moz, error);
}
/*
* Handle encrypted PDF files
*/
error = pdf_decryptxref(moz->xref);
if (error)
pdfmoz_error(moz, error);
if (moz->xref->crypt)
{
error = pdf_setpassword(moz->xref->crypt, password);
// while (error)
// {
// fz_droperror(error);
// password = winpassword(moz, filename);
// if (!password)
// exit(1);
// error = pdf_setpassword(moz->xref->crypt, password);
if (error)
pdfmoz_warn(moz, "Invalid password.");
// }
}
/*
* Load page tree
*/
error = pdf_loadpagetree(&pages, moz->xref);
if (error)
pdfmoz_error(moz, error);
moz->pagecount = pdf_getpagecount(pages);
moz->pages = fz_malloc(sizeof(page_t) * moz->pagecount);
for (i = 0; i < moz->pagecount; i++)
{
moz->pages[i].ref = fz_keepobj(pages->pref[i]);
moz->pages[i].obj = fz_keepobj(pdf_getpageobject(pages, i));
moz->pages[i].page = nil;
moz->pages[i].image = nil;
obj = fz_dictgets(moz->pages[i].obj, "CropBox");
if (!obj)
obj = fz_dictgets(moz->pages[i].obj, "MediaBox");
bbox = fz_roundrect(pdf_torect(obj));
moz->pages[i].w = bbox.x1 - bbox.x0;
moz->pages[i].h = bbox.y1 - bbox.y0;
rot = fz_toint(fz_dictgets(moz->pages[i].obj, "Rotate"));
if ((rot / 90) % 2)
{
int t = moz->pages[i].w;
moz->pages[i].w = moz->pages[i].h;
moz->pages[i].h = t;
}
moz->pages[i].px = 1 + PAD;
}
pdf_droppagetree(pages);
/*
* Load meta information
* TODO: move this into mupdf library
*/
obj = fz_dictgets(moz->xref->trailer, "Root");
if (!obj)
pdfmoz_error(moz, fz_throw("syntaxerror: missing Root object"));
error = pdf_loadindirect(&moz->xref->root, moz->xref, obj);
if (error)
pdfmoz_error(moz, error);
obj = fz_dictgets(moz->xref->trailer, "Info");
if (obj)
{
error = pdf_loadindirect(&moz->xref->info, moz->xref, obj);
if (error)
pdfmoz_error(moz, error);
}
error = pdf_loadnametrees(moz->xref);
if (error)
pdfmoz_error(moz, error);
moz->doctitle = filename;
if (strrchr(moz->doctitle, '\\'))
moz->doctitle = strrchr(moz->doctitle, '\\') + 1;
if (strrchr(moz->doctitle, '/'))
moz->doctitle = strrchr(moz->doctitle, '/') + 1;
if (moz->xref->info)
{
obj = fz_dictgets(moz->xref->info, "Title");
if (obj)
{
error = pdf_toutf8(&moz->doctitle, obj);
if (error)
pdfmoz_error(moz, error);
}
}
/*
* Start at first page
*/
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE; // XXX | SIF_PAGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = 1;
si.nPage = 1;
SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE);
moz->scrollpage = 0;
moz->scrollyofs = 0;
InvalidateRect(moz->hwnd, NULL, FALSE);
}
static void decodescroll(pdfmoz_t *moz, int spos)
{
int i, y = 0;
moz->scrollpage = 0;
moz->scrollyofs = 0;
for (i = 0; i < moz->pagecount; i++)
{
if (spos >= y && spos < y + moz->pages[i].px)
{
moz->scrollpage = i;
moz->scrollyofs = spos - y;
return;
}
y += moz->pages[i].px;
}
}
fz_matrix pdfmoz_pagectm(pdfmoz_t *moz, int pagenum)
{
page_t *page = moz->pages + pagenum;
fz_matrix ctm;
float zoom;
RECT rc;
GetClientRect(moz->hwnd, &rc);
zoom = (rc.right - rc.left) / (float) page->w;
ctm = fz_identity();
ctm = fz_concat(ctm, fz_translate(0, -page->page->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
ctm = fz_concat(ctm, fz_rotate(page->page->rotate));
return ctm;
}
void pdfmoz_loadpage(pdfmoz_t *moz, int pagenum)
{
page_t *page = moz->pages + pagenum;
fz_error *error;
if (page->page)
return;
error = pdf_loadpage(&page->page, moz->xref, page->obj);
if (error)
pdfmoz_error(moz, error);
}
void pdfmoz_drawpage(pdfmoz_t *moz, int pagenum)
{
page_t *page = moz->pages + pagenum;
fz_error *error;
fz_matrix ctm;
fz_rect bbox;
if (page->image)
return;
ctm = pdfmoz_pagectm(moz, pagenum);
bbox = fz_transformaabb(ctm, page->page->mediabox);
error = fz_rendertree(&page->image, moz->rast, page->page->tree,
ctm, fz_roundrect(bbox), 1);
if (error)
pdfmoz_error(moz, error);
}
void pdfmoz_gotouri(pdfmoz_t *moz, fz_obj *uri)
{
char buf[2048];
memcpy(buf, fz_tostrbuf(uri), fz_tostrlen(uri));
buf[fz_tostrlen(uri)] = 0;
NPN_GetURL(moz->inst, buf, "_blank");
}
int pdfmoz_getpagenum(pdfmoz_t *moz, fz_obj *obj)
{
int oid = fz_tonum(obj);
int i;
for (i = 0; i < moz->pagecount; i++)
if (fz_tonum(moz->pages[i].ref) == oid)
return i;
return 0;
}
void pdfmoz_gotopage(pdfmoz_t *moz, fz_obj *obj)
{
int oid = fz_tonum(obj);
int i, y = 0;
for (i = 0; i < moz->pagecount; i++)
{
if (fz_tonum(moz->pages[i].ref) == oid)
{
SetScrollPos(moz->hwnd, SB_VERT, y, TRUE);
InvalidateRect(moz->hwnd, NULL, FALSE);
return;
}
y += moz->pages[i].px;
}
}
void pdfmoz_onmouse(pdfmoz_t *moz, int x, int y, int click)
{
char buf[512];
pdf_link *link;
fz_matrix ctm;
fz_point p;
int pi;
int py;
if (!moz->pages)
return;
pi = moz->scrollpage;
py = -moz->scrollyofs;
while (pi < moz->pagecount)
{
if (!moz->pages[pi].image)
return;
if (y > py && y < moz->pages[pi].px)
break;
py += moz->pages[pi].px;
pi ++;
}
if (pi == moz->pagecount)
return;
p.x = x + moz->pages[pi].image->x;
p.y = y + moz->pages[pi].image->y - py;
ctm = pdfmoz_pagectm(moz, pi);
ctm = fz_invertmatrix(ctm);
p = fz_transformpoint(ctm, p);
for (link = moz->pages[pi].page->links; link; link = link->next)
{
if (p.x >= link->rect.x0 && p.x <= link->rect.x1)
if (p.y >= link->rect.y0 && p.y <= link->rect.y1)
break;
}
if (link)
{
SetCursor(moz->hand);
if (click)
{
if (fz_isstring(link->dest))
pdfmoz_gotouri(moz, link->dest);
if (fz_isindirect(link->dest))
pdfmoz_gotopage(moz, link->dest);
return;
}
else
{
if (fz_isstring(link->dest))
{
memcpy(buf, fz_tostrbuf(link->dest), fz_tostrlen(link->dest));
buf[fz_tostrlen(link->dest)] = 0;
NPN_Status(moz->inst, buf);
}
else if (fz_isindirect(link->dest))
{
sprintf(buf, "Go to page %d",
pdfmoz_getpagenum(moz, link->dest) + 1);
NPN_Status(moz->inst, buf);
}
else
NPN_Status(moz->inst, "Say what?");
}
}
else
{
sprintf(buf, "Page %d of %d", moz->scrollpage + 1, moz->pagecount);
NPN_Status(moz->inst, buf);
SetCursor(moz->arrow);
}
}
static void drawimage(HDC hdc, pdfmoz_t *moz, fz_pixmap *image, int yofs)
{
int bmpstride = ((image->w * 3 + 3) / 4) * 4;
char *bmpdata = fz_malloc(image->h * bmpstride);
int x, y;
if (!bmpdata)
return;
for (y = 0; y < image->h; y++)
{
char *p = bmpdata + y * bmpstride;
char *s = image->samples + y * image->w * 4;
for (x = 0; x < image->w; x++)
{
p[x * 3 + 0] = s[x * 4 + 3];
p[x * 3 + 1] = s[x * 4 + 2];
p[x * 3 + 2] = s[x * 4 + 1];
}
}
moz->dibinf->bmiHeader.biWidth = image->w;
moz->dibinf->bmiHeader.biHeight = -image->h;
moz->dibinf->bmiHeader.biSizeImage = image->h * bmpstride;
SetDIBitsToDevice(hdc,
0, /* destx */
yofs, /* desty */
image->w, /* destw */
image->h, /* desth */
0, /* srcx */
0, /* srcy */
0, /* startscan */
image->h, /* numscans */
bmpdata, /* pBits */
moz->dibinf, /* pInfo */
DIB_RGB_COLORS /* color use flag */
);
fz_free(bmpdata);
}
LRESULT CALLBACK
MozWinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
pdfmoz_t *moz = (pdfmoz_t*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
char buf[256];
int x = (signed short) LOWORD(lParam);
int y = (signed short) HIWORD(lParam);
int i, h;
SCROLLINFO si;
PAINTSTRUCT ps;
HDC hdc;
RECT rc;
RECT pad;
WORD sendmsg;
float zoom;
GetClientRect(hwnd, &rc);
h = rc.bottom - rc.top;
if (strlen(moz->error))
{
if (msg == WM_PAINT)
{
hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &rc, GetStockBrush(WHITE_BRUSH));
rc.top += 10;
rc.bottom -= 10;
rc.left += 10;
rc.right -= 10;
DrawText(hdc, moz->error, strlen(moz->error), &rc, 0);
// DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd, &ps);
}
if (msg == WM_MOUSEMOVE)
{
SetCursor(moz->arrow);
}
return 0;
}
switch (msg)
{
case WM_PAINT:
GetClientRect(moz->hwnd, &rc);
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
decodescroll(moz, si.nPos);
/* evict out-of-range images and pages */
for (i = 0; i < moz->pagecount; i++)
{
if (i < moz->scrollpage - 2 || i > moz->scrollpage + 6)
{
if (moz->pages[i].page)
{
pdf_droppage(moz->pages[i].page);
moz->pages[i].page = nil;
}
}
if (i < moz->scrollpage - 1 || i > moz->scrollpage + 3)
{
if (moz->pages[i].image)
{
fz_droppixmap(moz->pages[i].image);
moz->pages[i].image = nil;
}
}
}
i = moz->scrollpage;
pdfmoz_loadpage(moz, i);
if (moz->error[0]) return 0;
pdfmoz_drawpage(moz, i);
if (moz->error[0]) return 0;
y = -moz->scrollyofs;
while (y < h && i < moz->pagecount)
{
pdfmoz_loadpage(moz, i);
if (moz->error[0]) return 0;
pdfmoz_drawpage(moz, i);
if (moz->error[0]) return 0;
y += moz->pages[i].image->h;
i ++;
}
hdc = BeginPaint(hwnd, &ps);
pad.left = rc.left;
pad.right = rc.right;
i = moz->scrollpage;
y = -moz->scrollyofs;
while (y < h && i < moz->pagecount)
{
drawimage(hdc, moz, moz->pages[i].image, y);
y += moz->pages[i].image->h;
i ++;
pad.top = y;
pad.bottom = y + PAD;
FillRect(hdc, &pad, moz->graybrush);
y += PAD;
}
if (y < h)
{
pad.top = y;
pad.bottom = h;
FillRect(hdc, &pad, moz->graybrush);
}
EndPaint(hwnd, &ps);
return 0;
case WM_SIZE:
ShowScrollBar(moz->hwnd, SB_VERT, TRUE);
GetClientRect(moz->hwnd, &rc);
si.cbSize = sizeof(si);
si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
si.nPos = 0;
si.nMin = 0;
si.nMax = 0;
// si.nPage = MAX(30, rc.bottom - rc.top - 30);
si.nPage = rc.bottom - rc.top;
for (i = 0; i < moz->pagecount; i++)
{
zoom = (rc.right - rc.left) / (float) moz->pages[i].w;
moz->pages[i].px = zoom * moz->pages[i].h + PAD;
if (moz->scrollpage == i)
{
si.nPos = si.nMax;
if (moz->pages[i].image)
{
si.nPos +=
moz->pages[i].px *
moz->scrollyofs /
moz->pages[i].image->h + 1;
}
}
if (moz->pages[i].image)
{
fz_droppixmap(moz->pages[i].image);
moz->pages[i].image = nil;
}
si.nMax += moz->pages[i].px;
}
si.nMax --;
SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE);
break;
case WM_MOUSEMOVE:
pdfmoz_onmouse(moz, x, y, 0);
break;
case WM_LBUTTONDOWN:
SetFocus(hwnd);
pdfmoz_onmouse(moz, x, y, 1);
break;
case WM_VSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
switch (LOWORD(wParam))
{
case SB_BOTTOM: si.nPos = si.nMax; break;
case SB_TOP: si.nPos = 0; break;
case SB_LINEUP: si.nPos -= 50; break;
case SB_LINEDOWN: si.nPos += 50; break;
case SB_PAGEUP: si.nPos -= si.nPage; break;
case SB_PAGEDOWN: si.nPos += si.nPage; break;
case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
case SB_THUMBPOSITION: si.nPos = si.nTrackPos; break;
}
si.fMask = SIF_POS;
si.nPos = MAX(0, MIN(si.nPos, si.nMax));
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
InvalidateRect(moz->hwnd, NULL, FALSE);
decodescroll(moz, si.nPos);
sprintf(buf, "Page %d of %d", moz->scrollpage + 1, moz->pagecount);
NPN_Status(moz->inst, buf);
return 0;
case WM_MOUSEWHEEL:
if ((signed short)HIWORD(wParam) > 0)
SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
else
SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
break;
case WM_KEYDOWN:
sendmsg = 0xFFFF;
switch (wParam)
{
case VK_UP: sendmsg = SB_LINEUP; break;
case VK_PRIOR: sendmsg = SB_PAGEUP; break;
case ' ':
case VK_NEXT: sendmsg = SB_PAGEDOWN; break;
case '\r':
case VK_DOWN: sendmsg = SB_LINEDOWN; break;
case VK_HOME: sendmsg = SB_TOP; break;
case VK_END: sendmsg = SB_BOTTOM; break;
}
if (sendmsg != 0xFFFF)
SendMessage(hwnd, WM_VSCROLL, MAKELONG(sendmsg, 0), 0);
/* ick! someone eats events instead of bubbling... not my fault! */
break;
default:
break;
}
return moz->winproc(hwnd, msg, wParam, lParam);
}
NPError
NPP_New(NPMIMEType mime, NPP inst, uint16 mode,
int16 argc, char *argn[], char *argv[], NPSavedData *saved)
{
pdfmoz_t *moz;
//MSG("NPP_New");
moz = fz_malloc(sizeof(pdfmoz_t));
if (!moz)
return NPERR_OUT_OF_MEMORY_ERROR;
memset(moz, 0, sizeof(pdfmoz_t));
sprintf(moz->error, "MuPDF is loading the file...");
moz->inst = inst;
moz->arrow = LoadCursor(NULL, IDC_ARROW);
moz->hand = LoadCursor(NULL, IDC_HAND);
moz->wait = LoadCursor(NULL, IDC_WAIT);
moz->dibinf = fz_malloc(sizeof(BITMAPINFO) + 12);
if (!moz->dibinf)
return NPERR_OUT_OF_MEMORY_ERROR;
moz->dibinf->bmiHeader.biSize = sizeof(moz->dibinf->bmiHeader);
moz->dibinf->bmiHeader.biPlanes = 1;
moz->dibinf->bmiHeader.biBitCount = 24;
moz->dibinf->bmiHeader.biCompression = BI_RGB;
moz->dibinf->bmiHeader.biXPelsPerMeter = 2834;
moz->dibinf->bmiHeader.biYPelsPerMeter = 2834;
moz->dibinf->bmiHeader.biClrUsed = 0;
moz->dibinf->bmiHeader.biClrImportant = 0;
moz->dibinf->bmiHeader.biClrUsed = 0;
moz->graybrush = CreateSolidBrush(RGB(0x70,0x70,0x70));
inst->pdata = moz;
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP inst, NPSavedData **saved)
{
pdfmoz_t *moz = inst->pdata;
int i;
//MSG("NPP_Destroy");
inst->pdata = NULL;
DeleteObject(moz->graybrush);
DestroyCursor(moz->arrow);
DestroyCursor(moz->hand);
DestroyCursor(moz->wait);
fz_free(moz->dibinf);
for (i = 0; i < moz->pagecount; i++)
{
if (moz->pages[i].obj)
fz_dropobj(moz->pages[i].obj);
if (moz->pages[i].page)
pdf_droppage(moz->pages[i].page);
if (moz->pages[i].image)
fz_droppixmap(moz->pages[i].image);
}
fz_free(moz->pages);
if (moz->xref)
{
if (moz->xref->store)
{
pdf_dropstore(moz->xref->store);
moz->xref->store = nil;
}
pdf_closexref(moz->xref);
}
fz_free(moz);
return NPERR_NO_ERROR;
}
NPError
NPP_SetWindow(NPP inst, NPWindow *npwin)
{
pdfmoz_t *moz = inst->pdata;
if (moz->hwnd != npwin->window)
{
moz->hwnd = npwin->window;
SetWindowLongPtr(moz->hwnd, GWLP_USERDATA, (LONG_PTR)moz);
moz->winproc = (WNDPROC)
SetWindowLongPtr(moz->hwnd, GWLP_WNDPROC, (LONG_PTR)MozWinProc);
}
SetFocus(moz->hwnd);
return NPERR_NO_ERROR;
}
NPError
NPP_NewStream(NPP inst, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16* stype)
{
//MSG("NPP_NewStream");
*stype = NP_ASFILE;
return NPERR_NO_ERROR;
}
NPError
NPP_DestroyStream(NPP inst, NPStream* stream, NPReason reason)
{
//MSG("NPP_DestroyStream");
return NPERR_NO_ERROR;
}
int32
NPP_WriteReady(NPP inst, NPStream* stream)
{
//MSG("NPP_WriteReady");
return 2147483647;
}
int32
NPP_Write(NPP inst, NPStream* stream, int32 offset, int32 len, void* buffer)
{
//MSG("NPP_Write");
return len;
}
void
NPP_StreamAsFile(NPP inst, NPStream* stream, const char* fname)
{
pdfmoz_t *moz = inst->pdata;
//MSG("NPP_StreamAsFile");
pdfmoz_open(moz, (char*)fname);
}
void
NPP_Print(NPP inst, NPPrint* platformPrint)
{
MSG("Sorry, printing is not supported.");
}
int16
NPP_HandleEvent(NPP inst, void* event)
{
MSG("handle event\n");
return 0;
}
void
NPP_URLNotify(NPP inst, const char* url,
NPReason reason, void* notifyData)
{
MSG("notify url\n");
}
NPError
NPP_GetValue(void* inst, NPPVariable variable, void *value)
{
return NPERR_NO_ERROR;
}
NPError
NPP_SetValue(void* inst, NPNVariable variable, void *value)
{
return NPERR_NO_ERROR;
}
void* NPP_GetJavaClass(void)
{
return 0;
}
NPError
NPP_Initialize(void)
{
// MSG("NPP_Initialize");
return NPERR_NO_ERROR;
}
void
NPP_Shutdown(void)
{
// MSG("NPP_Shutdown");
}

View file

@ -1,21 +0,0 @@
//
// MuPDF Plugin description
//
1 VERSIONINFO
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "ProductName", "MuPDF Plug-in\0"
VALUE "OriginalFilename", "npmupdf.dll\0"
VALUE "FileDescription", "The MuPDF plugin allows you to browse PDF files with a simple light-weight scrolling interface.\0"
VALUE "MIMEType", "application/pdf|application/x-mupdf\0"
VALUE "FileExtents", "pdf|foo"
VALUE "FileOpenName", "Acrobat PDF File|Acrobat PDF File"
END
END
END

View file

@ -1,469 +0,0 @@
/* -*- Mode: C; tab-width: 4; -*- */
/*
* npapi.h $Revision: 1.88 $
* Netscape client plug-in API spec
*/
#ifndef _NPAPI_H_
#define _NPAPI_H_
#include "jri.h" /* Java Runtime Interface */
#ifdef _WINDOWS
# ifndef XP_WIN
# define XP_WIN 1
# endif /* XP_WIN */
#endif /* _WINDOWS */
#ifdef __MWERKS__
# define _declspec __declspec
# ifdef macintosh
# ifndef XP_MAC
# define XP_MAC 1
# endif /* XP_MAC */
# endif /* macintosh */
# ifdef __INTEL__
# undef NULL
# ifndef XP_WIN
# define XP_WIN 1
# endif /* __INTEL__ */
# endif /* XP_PC */
#endif /* __MWERKS__ */
#ifdef XP_MAC
#include <Quickdraw.h>
#include <Events.h>
#endif
#ifdef XP_UNIX
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
/*----------------------------------------------------------------------*/
/* Plugin Version Constants */
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 11
/*----------------------------------------------------------------------*/
/* Definition of Basic Types */
/*----------------------------------------------------------------------*/
#ifndef _UINT16
typedef unsigned short uint16;
#endif
#ifndef _UINT32
#if defined(__alpha)
typedef unsigned int uint32;
#else /* __alpha */
typedef unsigned long uint32;
#endif /* __alpha */
#endif
#ifndef _INT16
typedef short int16;
#endif
#ifndef _INT32
#if defined(__alpha)
typedef int int32;
#else /* __alpha */
typedef long int32;
#endif /* __alpha */
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef NULL
#define NULL (0L)
#endif
typedef unsigned char NPBool;
typedef int16 NPError;
typedef int16 NPReason;
typedef char* NPMIMEType;
/*----------------------------------------------------------------------*/
/* Structures and definitions */
/*----------------------------------------------------------------------*/
#ifdef XP_MAC
#pragma options align=mac68k
#endif
/*
* NPP is a plug-in's opaque instance handle
*/
typedef struct _NPP
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
} NPP_t;
typedef NPP_t* NPP;
typedef struct _NPStream
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
const char* url;
uint32 end;
uint32 lastmodified;
void* notifyData;
} NPStream;
typedef struct _NPByteRange
{
int32 offset; /* negative offset means from the end */
uint32 length;
struct _NPByteRange* next;
} NPByteRange;
typedef struct _NPSavedData
{
int32 len;
void* buf;
} NPSavedData;
typedef struct _NPRect
{
uint16 top;
uint16 left;
uint16 bottom;
uint16 right;
} NPRect;
#ifdef XP_UNIX
/*
* Unix specific structures and definitions
*/
/*
* Callback Structures.
*
* These are used to pass additional platform specific information.
*/
enum {
NP_SETWINDOW = 1,
NP_PRINT
};
typedef struct
{
int32 type;
} NPAnyCallbackStruct;
typedef struct
{
int32 type;
Display* display;
Visual* visual;
Colormap colormap;
unsigned int depth;
} NPSetWindowCallbackStruct;
typedef struct
{
int32 type;
FILE* fp;
} NPPrintCallbackStruct;
#endif /* XP_UNIX */
/*
* List of variable names for which NPP_GetValue shall be implemented
*/
typedef enum {
NPPVpluginNameString = 1,
NPPVpluginDescriptionString,
NPPVpluginWindowBool,
NPPVpluginTransparentBool
} NPPVariable;
/*
* List of variable names for which NPN_GetValue is implemented by Mozilla
*/
typedef enum {
NPNVxDisplay = 1,
NPNVxtAppContext,
NPNVnetscapeWindow,
NPNVjavascriptEnabledBool,
NPNVasdEnabledBool,
NPNVisOfflineBool
} NPNVariable;
/*
* The type of a NPWindow - it specifies the type of the data structure
* returned in the window field.
*/
typedef enum {
NPWindowTypeWindow = 1,
NPWindowTypeDrawable
} NPWindowType;
typedef struct _NPWindow
{
void* window; /* Platform specific window handle */
int32 x; /* Position of top left corner relative */
int32 y; /* to a netscape page. */
uint32 width; /* Maximum window size */
uint32 height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
#ifdef XP_UNIX
void * ws_info; /* Platform-dependent additonal data */
#endif /* XP_UNIX */
NPWindowType type; /* Is this a window or a drawable? */
} NPWindow;
typedef struct _NPFullPrint
{
NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */
/* printing */
NPBool printOne; /* TRUE if plugin should print one copy */
/* to default printer */
void* platformPrint; /* Platform-specific printing info */
} NPFullPrint;
typedef struct _NPEmbedPrint
{
NPWindow window;
void* platformPrint; /* Platform-specific printing info */
} NPEmbedPrint;
typedef struct _NPPrint
{
uint16 mode; /* NP_FULL or NP_EMBED */
union
{
NPFullPrint fullPrint; /* if mode is NP_FULL */
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
} print;
} NPPrint;
#ifdef XP_MAC
typedef EventRecord NPEvent;
#elif defined(XP_WIN)
typedef struct _NPEvent
{
uint16 event;
uint32 wParam;
uint32 lParam;
} NPEvent;
#elif defined (XP_UNIX)
typedef XEvent NPEvent;
#else
typedef void* NPEvent;
#endif /* XP_MAC */
#ifdef XP_MAC
typedef RgnHandle NPRegion;
#elif defined(XP_WIN)
typedef HRGN NPRegion;
#elif defined(XP_UNIX)
typedef Region NPRegion;
#else
typedef void *NPRegion;
#endif /* XP_MAC */
#ifdef XP_MAC
/*
* Mac-specific structures and definitions.
*/
typedef struct NP_Port
{
CGrafPtr port; /* Grafport */
int32 portx; /* position inside the topmost window */
int32 porty;
} NP_Port;
/*
* Non-standard event types that can be passed to HandleEvent
*/
#define getFocusEvent (osEvt + 16)
#define loseFocusEvent (osEvt + 17)
#define adjustCursorEvent (osEvt + 18)
#endif /* XP_MAC */
/*
* Values for mode passed to NPP_New:
*/
#define NP_EMBED 1
#define NP_FULL 2
/*
* Values for stream type passed to NPP_NewStream:
*/
#define NP_NORMAL 1
#define NP_SEEK 2
#define NP_ASFILE 3
#define NP_ASFILEONLY 4
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
#ifdef XP_MAC
#pragma options align=reset
#endif
/*----------------------------------------------------------------------*/
/* Error and Reason Code definitions */
/*----------------------------------------------------------------------*/
/*
* Values of type NPError:
*/
#define NPERR_BASE 0
#define NPERR_NO_ERROR (NPERR_BASE + 0)
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
#define NPERR_INVALID_URL (NPERR_BASE + 10)
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
#define NPERR_NO_DATA (NPERR_BASE + 12)
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
/*
* Values of type NPReason:
*/
#define NPRES_BASE 0
#define NPRES_DONE (NPRES_BASE + 0)
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
#define NPRES_USER_BREAK (NPRES_BASE + 2)
/*
* Don't use these obsolete error codes any more.
*/
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
/*
* Version feature information
*/
#define NPVERS_HAS_STREAMOUTPUT 8
#define NPVERS_HAS_NOTIFICATION 9
#define NPVERS_HAS_LIVECONNECT 9
#define NPVERS_WIN16_HAS_LIVECONNECT 9
#define NPVERS_68K_HAS_LIVECONNECT 11
#define NPVERS_HAS_WINDOWLESS 11
/*----------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------*/
#if defined(_WINDOWS) && !defined(WIN32)
#define NP_LOADDS _loadds
#else
#define NP_LOADDS
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* NPP_* functions are provided by the plugin and called by the navigator.
*/
#ifdef XP_UNIX
char* NPP_GetMIMEDescription(void);
#endif /* XP_UNIX */
NPError NPP_Initialize(void);
void NPP_Shutdown(void);
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
uint16 mode, int16 argc, char* argn[],
char* argv[], NPSavedData* saved);
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16* stype);
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset,
int32 len, void* buffer);
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
const char* fname);
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
int16 NPP_HandleEvent(NPP instance, void* event);
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData);
jref NP_LOADDS NPP_GetJavaClass(void);
NPError NPP_GetValue(void *instance, NPPVariable variable,
void *value);
NPError NPP_SetValue(void *instance, NPNVariable variable,
void *value);
/*
* NPN_* functions are provided by the navigator and called by the plugin.
*/
void NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor);
NPError NPN_GetURLNotify(NPP instance, const char* url,
const char* target, void* notifyData);
NPError NPN_GetURL(NPP instance, const char* url,
const char* target);
NPError NPN_PostURLNotify(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file,
void* notifyData);
NPError NPN_PostURL(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file);
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
NPError NPN_NewStream(NPP instance, NPMIMEType type,
const char* target, NPStream** stream);
int32 NPN_Write(NPP instance, NPStream* stream, int32 len,
void* buffer);
NPError NPN_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
void NPN_Status(NPP instance, const char* message);
const char* NPN_UserAgent(NPP instance);
void* NPN_MemAlloc(uint32 size);
void NPN_MemFree(void* ptr);
uint32 NPN_MemFlush(uint32 size);
void NPN_ReloadPlugins(NPBool reloadPages);
JRIEnv* NPN_GetJavaEnv(void);
jref NPN_GetJavaPeer(NPP instance);
NPError NPN_GetValue(NPP instance, NPNVariable variable,
void *value);
NPError NPN_SetValue(NPP instance, NPPVariable variable,
void *value);
void NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion);
void NPN_ForceRedraw(NPP instance);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* _NPAPI_H_ */

View file

@ -1,406 +0,0 @@
/*
* npunix.c
*
* Netscape Client Plugin API
* - Wrapper function to interface with the Netscape Navigator
*
* dp Suresh <dp@netscape.com>
*
*----------------------------------------------------------------------
* PLUGIN DEVELOPERS:
* YOU WILL NOT NEED TO EDIT THIS FILE.
*----------------------------------------------------------------------
*/
#define XP_UNIX 1
#include <stdio.h>
#include "npapi.h"
#include "npupp.h"
/*
* Define PLUGIN_TRACE to have the wrapper functions print
* messages to stderr whenever they are called.
*/
#ifdef PLUGIN_TRACE
#include <stdio.h>
#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg)
#else
#define PLUGINDEBUGSTR(msg)
#endif
/***********************************************************************
*
* Globals
*
***********************************************************************/
static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
/***********************************************************************
*
* Wrapper functions : plugin calling Netscape Navigator
*
* These functions let the plugin developer just call the APIs
* as documented and defined in npapi.h, without needing to know
* about the function table and call macros in npupp.h.
*
***********************************************************************/
void
NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor)
{
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
/* Major version is in high byte */
*netscape_major = gNetscapeFuncs.version >> 8;
/* Minor version is in low byte */
*netscape_minor = gNetscapeFuncs.version & 0xFF;
}
NPError
NPN_GetValue(NPP instance, NPNVariable variable, void *r_value)
{
return CallNPN_GetValueProc(gNetscapeFuncs.getvalue,
instance, variable, r_value);
}
NPError
NPN_GetURL(NPP instance, const char* url, const char* window)
{
return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
}
NPError
NPN_PostURL(NPP instance, const char* url, const char* window,
uint32 len, const char* buf, NPBool file)
{
return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance,
url, window, len, buf, file);
}
NPError
NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
return CallNPN_RequestReadProc(gNetscapeFuncs.requestread,
stream, rangeList);
}
NPError
NPN_NewStream(NPP instance, NPMIMEType type, const char *window,
NPStream** stream_ptr)
{
return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance,
type, window, stream_ptr);
}
int32
NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
{
return CallNPN_WriteProc(gNetscapeFuncs.write, instance,
stream, len, buffer);
}
NPError
NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream,
instance, stream, reason);
}
void
NPN_Status(NPP instance, const char* message)
{
CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
}
const char*
NPN_UserAgent(NPP instance)
{
return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
}
void*
NPN_MemAlloc(uint32 size)
{
return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
}
void NPN_MemFree(void* ptr)
{
CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
}
uint32 NPN_MemFlush(uint32 size)
{
return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
}
void NPN_ReloadPlugins(NPBool reloadPages)
{
CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
}
JRIEnv* NPN_GetJavaEnv()
{
return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv);
}
jref NPN_GetJavaPeer(NPP instance)
{
return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer,
instance);
}
/***********************************************************************
*
* Wrapper functions : Netscape Navigator -> plugin
*
* These functions let the plugin developer just create the APIs
* as documented and defined in npapi.h, without needing to
* install those functions in the function table or worry about
* setting up globals for 68K plugins.
*
***********************************************************************/
NPError
Private_New(NPMIMEType pluginType, NPP instance, uint16 mode,
int16 argc, char* argn[], char* argv[], NPSavedData* saved)
{
NPError ret;
PLUGINDEBUGSTR("New");
ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
return ret;
}
NPError
Private_Destroy(NPP instance, NPSavedData** save)
{
PLUGINDEBUGSTR("Destroy");
return NPP_Destroy(instance, save);
}
NPError
Private_SetWindow(NPP instance, NPWindow* window)
{
NPError err;
PLUGINDEBUGSTR("SetWindow");
err = NPP_SetWindow(instance, window);
return err;
}
NPError
Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype)
{
NPError err;
PLUGINDEBUGSTR("NewStream");
err = NPP_NewStream(instance, type, stream, seekable, stype);
return err;
}
int32
Private_WriteReady(NPP instance, NPStream* stream)
{
unsigned int result;
PLUGINDEBUGSTR("WriteReady");
result = NPP_WriteReady(instance, stream);
return result;
}
int32
Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
void* buffer)
{
unsigned int result;
PLUGINDEBUGSTR("Write");
result = NPP_Write(instance, stream, offset, len, buffer);
return result;
}
void
Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
PLUGINDEBUGSTR("StreamAsFile");
NPP_StreamAsFile(instance, stream, fname);
}
NPError
Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
NPError err;
PLUGINDEBUGSTR("DestroyStream");
err = NPP_DestroyStream(instance, stream, reason);
return err;
}
void
Private_Print(NPP instance, NPPrint* platformPrint)
{
PLUGINDEBUGSTR("Print");
NPP_Print(instance, platformPrint);
}
JRIGlobalRef
Private_GetJavaClass(void)
{
jref clazz = NPP_GetJavaClass();
if (clazz) {
JRIEnv* env = NPN_GetJavaEnv();
return JRI_NewGlobalRef(env, clazz);
}
return NULL;
}
/***********************************************************************
*
* These functions are located automagically by netscape.
*
***********************************************************************/
/*
* NP_GetMIMEDescription
* - Netscape needs to know about this symbol
* - Netscape uses the return value to identify when an object instance
* of this plugin should be created.
*/
char *
NP_GetMIMEDescription(void)
{
return NPP_GetMIMEDescription();
}
/*
* NP_GetValue [optional]
* - Netscape needs to know about this symbol.
* - Interfaces with plugin to get values for predefined variables
* that the navigator needs.
*/
NPError
NP_GetValue(void *future, NPPVariable variable, void *value)
{
return NPP_GetValue(future, variable, value);
}
/*
* NP_Initialize
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol before it
* is about to create the first ever object of this kind.
*
* PARAMETERS
* nsTable - The netscape function table. If developers just use these
* wrappers, they dont need to worry about all these function
* tables.
* RETURN
* pluginFuncs
* - This functions needs to fill the plugin function table
* pluginFuncs and return it. Netscape Navigator plugin
* library will use this function table to call the plugin.
*
*/
NPError
NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs)
{
NPError err = NPERR_NO_ERROR;
PLUGINDEBUGSTR("NP_Initialize");
/* validate input parameters */
if ((nsTable == NULL) || (pluginFuncs == NULL))
err = NPERR_INVALID_FUNCTABLE_ERROR;
/*
* Check the major version passed in Netscape's function table.
* We won't load if the major version is newer than what we expect.
* Also check that the function tables passed in are big enough for
* all the functions we need (they could be bigger, if Netscape added
* new APIs, but that's OK with us -- we'll just ignore them).
*
*/
if (err == NPERR_NO_ERROR) {
if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
if (nsTable->size < sizeof(NPNetscapeFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
if (pluginFuncs->size < sizeof(NPPluginFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
}
if (err == NPERR_NO_ERROR) {
/*
* Copy all the fields of Netscape function table into our
* copy so we can call back into Netscape later. Note that
* we need to copy the fields one by one, rather than assigning
* the whole structure, because the Netscape function table
* could actually be bigger than what we expect.
*/
gNetscapeFuncs.version = nsTable->version;
gNetscapeFuncs.size = nsTable->size;
gNetscapeFuncs.posturl = nsTable->posturl;
gNetscapeFuncs.geturl = nsTable->geturl;
gNetscapeFuncs.requestread = nsTable->requestread;
gNetscapeFuncs.newstream = nsTable->newstream;
gNetscapeFuncs.write = nsTable->write;
gNetscapeFuncs.destroystream = nsTable->destroystream;
gNetscapeFuncs.status = nsTable->status;
gNetscapeFuncs.uagent = nsTable->uagent;
gNetscapeFuncs.memalloc = nsTable->memalloc;
gNetscapeFuncs.memfree = nsTable->memfree;
gNetscapeFuncs.memflush = nsTable->memflush;
gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
gNetscapeFuncs.getvalue = nsTable->getvalue;
/*
* Set up the plugin function table that Netscape will use to
* call us. Netscape needs to know about our version and size
* and have a UniversalProcPointer for every function we
* implement.
*/
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
pluginFuncs->size = sizeof(NPPluginFuncs);
pluginFuncs->newp = NewNPP_NewProc(Private_New);
pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
pluginFuncs->write = NewNPP_WriteProc(Private_Write);
pluginFuncs->print = NewNPP_PrintProc(Private_Print);
pluginFuncs->event = NULL;
pluginFuncs->javaClass = Private_GetJavaClass();
err = NPP_Initialize();
}
return err;
}
/*
* NP_Shutdown [optional]
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol after
* the last object of this kind has been destroyed.
*
*/
NPError
NP_Shutdown(void)
{
PLUGINDEBUGSTR("NP_Shutdown");
NPP_Shutdown();
return NPERR_NO_ERROR;
}

File diff suppressed because it is too large Load diff

View file

@ -1,327 +0,0 @@
/* npwin.cpp */
//\\// INCLUDE
//#include "StdAfx.h"
// TOR
#include <windows.h>
// netscape
#ifndef _NPAPI_H_
#include "npapi.h"
#endif
#ifndef _NPUPP_H_
#include "npupp.h"
#endif
//\\// DEFINE
#ifdef WIN32
#define NP_EXPORT
#else
#define NP_EXPORT _export
#endif
//\\// GLOBAL DATA
NPNetscapeFuncs* g_pNavigatorFuncs = 0;
JRIGlobalRef Private_GetJavaClass(void);
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
// Private_GetJavaClass (global function)
//
// Given a Java class reference (thru NPP_GetJavaClass) inform JRT
// of this class existence
//
JRIGlobalRef
Private_GetJavaClass(void)
{
jref clazz = NPP_GetJavaClass();
if (clazz) {
JRIEnv* env = NPN_GetJavaEnv();
return JRI_NewGlobalRef(env, clazz);
}
return NULL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
// PLUGIN DLL entry points
//
// These are the Windows specific DLL entry points. They must be exoprted
//
// we need these to be global since we have to fill one of its field
// with a data (class) which requires knowlwdge of the navigator
// jump-table. This jump table is known at Initialize time (NP_Initialize)
// which is called after NP_GetEntryPoint
static NPPluginFuncs* g_pluginFuncs;
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
// NP_GetEntryPoints
//
// fills in the func table used by Navigator to call entry points in
// plugin DLL. Note that these entry points ensure that DS is loaded
// by using the NP_LOADDS macro, when compiling for Win16
//
NPError WINAPI NP_EXPORT
NP_GetEntryPoints(NPPluginFuncs* pFuncs)
{
// trap a NULL ptr
if(pFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
// if the plugin's function table is smaller than the plugin expects,
// then they are incompatible, and should return an error
pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
pFuncs->newp = NPP_New;
pFuncs->destroy = NPP_Destroy;
pFuncs->setwindow = NPP_SetWindow;
pFuncs->newstream = NPP_NewStream;
pFuncs->destroystream = NPP_DestroyStream;
pFuncs->asfile = NPP_StreamAsFile;
pFuncs->writeready = NPP_WriteReady;
pFuncs->write = NPP_Write;
pFuncs->print = NPP_Print;
pFuncs->event = 0; /// reserved
g_pluginFuncs = pFuncs;
return NPERR_NO_ERROR;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
// NP_Initialize
//
// called immediately after the plugin DLL is loaded
//
NPError WINAPI NP_EXPORT
NP_Initialize(NPNetscapeFuncs* pFuncs)
{
// trap a NULL ptr
if(pFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
g_pNavigatorFuncs = pFuncs; // save it for future reference
// if the plugin's major ver level is lower than the Navigator's,
// then they are incompatible, and should return an error
if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
// We have to defer these assignments until g_pNavigatorFuncs is set
int navMinorVers = g_pNavigatorFuncs->version & 0xFF;
if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) {
g_pluginFuncs->urlnotify = NPP_URLNotify;
}
#ifdef WIN32 // An ugly hack, because Win16 lags behind in Java
if( navMinorVers >= NPVERS_HAS_LIVECONNECT ) {
#else
if( navMinorVers >= NPVERS_WIN16_HAS_LIVECONNECT ) {
#endif // WIN32
g_pluginFuncs->javaClass = Private_GetJavaClass();
}
// NPP_Initialize is a standard (cross-platform) initialize function.
return NPP_Initialize();
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
// NP_Shutdown
//
// called immediately before the plugin DLL is unloaded.
// This functio shuold check for some ref count on the dll to see if it is
// unloadable or it needs to stay in memory.
//
NPError WINAPI NP_EXPORT
NP_Shutdown()
{
NPP_Shutdown();
g_pNavigatorFuncs = NULL;
return NPERR_NO_ERROR;
}
// END - PLUGIN DLL entry points
////\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//.
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\.
/* NAVIGATOR Entry points */
/* These entry points expect to be called from within the plugin. The
noteworthy assumption is that DS has already been set to point to the
plugin's DLL data segment. Don't call these functions from outside
the plugin without ensuring DS is set to the DLLs data segment first,
typically using the NP_LOADDS macro
*/
// TOR
void NPN_InvalidateRect(NPP instance, NPRect *rect)
{
return g_pNavigatorFuncs->invalidaterect(instance, rect);
}
/* returns the major/minor version numbers of the Plugin API for the plugin
and the Navigator
*/
void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor)
{
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
*netscape_major = HIBYTE(g_pNavigatorFuncs->version);
*netscape_minor = LOBYTE(g_pNavigatorFuncs->version);
}
/* causes the specified URL to be fetched and streamed in
*/
NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData)
{
int navMinorVers = g_pNavigatorFuncs->version & 0xFF;
NPError err;
if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) {
err = g_pNavigatorFuncs->geturlnotify(instance, url, target, notifyData);
}
else {
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
}
return err;
}
NPError NPN_GetURL(NPP instance, const char *url, const char *target)
{
return g_pNavigatorFuncs->geturl(instance, url, target);
}
NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData)
{
int navMinorVers = g_pNavigatorFuncs->version & 0xFF;
NPError err;
if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) {
err = g_pNavigatorFuncs->posturlnotify(instance, url, window, len, buf, file, notifyData);
}
else {
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
}
return err;
}
NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file)
{
return g_pNavigatorFuncs->posturl(instance, url, window, len, buf, file);
}
/* Requests that a number of bytes be provided on a stream. Typically
this would be used if a stream was in "pull" mode. An optional
position can be provided for streams which are seekable.
*/
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
return g_pNavigatorFuncs->requestread(stream, rangeList);
}
/* Creates a new stream of data from the plug-in to be interpreted
by Netscape in the current window.
*/
NPError NPN_NewStream(NPP instance, NPMIMEType type,
const char* target, NPStream** stream)
{
int navMinorVersion = g_pNavigatorFuncs->version & 0xFF;
NPError err;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) {
err = g_pNavigatorFuncs->newstream(instance, type, target, stream);
}
else {
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
}
return err;
}
/* Provides len bytes of data.
*/
int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer)
{
int navMinorVersion = g_pNavigatorFuncs->version & 0xFF;
int32 result;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) {
result = g_pNavigatorFuncs->write(instance, stream, len, buffer);
}
else {
result = -1;
}
return result;
}
/* Closes a stream object.
reason indicates why the stream was closed.
*/
NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
int navMinorVersion = g_pNavigatorFuncs->version & 0xFF;
NPError err;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) {
err = g_pNavigatorFuncs->destroystream(instance, stream, reason);
}
else {
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
}
return err;
}
/* Provides a text status message in the Netscape client user interface
*/
void NPN_Status(NPP instance, const char *message)
{
g_pNavigatorFuncs->status(instance, message);
}
/* returns the user agent string of Navigator, which contains version info
*/
const char* NPN_UserAgent(NPP instance)
{
return g_pNavigatorFuncs->uagent(instance);
}
/* allocates memory from the Navigator's memory space. Necessary so that
saved instance data may be freed by Navigator when exiting.
*/
void* NPN_MemAlloc(uint32 size)
{
return g_pNavigatorFuncs->memalloc(size);
}
/* reciprocal of MemAlloc() above
*/
void NPN_MemFree(void* ptr)
{
g_pNavigatorFuncs->memfree(ptr);
}
/* private function to Netscape. do not use!
*/
void NPN_ReloadPlugins(NPBool reloadPages)
{
g_pNavigatorFuncs->reloadplugins(reloadPages);
}
JRIEnv* NPN_GetJavaEnv(void)
{
return g_pNavigatorFuncs->getJavaEnv();
}
jref NPN_GetJavaPeer(NPP instance)
{
return g_pNavigatorFuncs->getJavaPeer(instance);
}

File diff suppressed because it is too large Load diff

View file

@ -1,188 +0,0 @@
#include "fitz.h"
#include "samus.h"
void die(fz_error *eo)
{
fflush(stdout);
fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
fflush(stderr);
abort();
}
void showfixdocseq(sa_package *pack, char *part)
{
fz_error *error;
sa_fixdocseq *seq;
error = sa_loadfixdocseq(&seq, pack, part);
if (error)
die(error);
sa_debugfixdocseq(seq);
sa_dropfixdocseq(seq);
}
void showreach(sa_package *pack, sa_relation *rels)
{
while (rels)
{
if (!strcmp(rels->type, SA_REL_FIXEDREPRESENTATION))
{
if (!rels->external)
showfixdocseq(pack, rels->target);
}
rels = rels->next;
}
}
int runpack(int argc, char **argv)
{
fz_error *error;
sa_package *pack;
sa_relation *rels;
char *s;
int i;
error = sa_openpackage(&pack, argv[1]);
if (error)
die(error);
sa_debugpackage(pack);
printf("\n");
error = sa_loadrelations(&rels, pack, "/");
if (error)
die(error);
sa_debugrelations(rels);
printf("\n");
if (argc == 2)
{
showreach(pack, rels);
return 0;
}
for (i = 2; i < argc; i++)
{
printf("part %s\n", argv[i]);
s = sa_typepart(pack, argv[i]);
if (!s)
printf("has no type!\n");
else
printf("type %s\n", s);
error = sa_loadrelations(&rels, pack, argv[i]);
if (error)
die(error);
sa_debugrelations(rels);
sa_droprelations(rels);
printf("\n");
}
sa_closepackage(pack);
return 0;
}
int runzip(int argc, char **argv)
{
fz_error *error;
fz_buffer *buf;
fz_stream *stm;
sa_zip *zip;
int i, n;
error = sa_openzip(&zip, argv[1]);
if (error)
die(error);
if (argc == 2)
sa_debugzip(zip);
for (i = 2; i < argc; i++)
{
error = sa_openzipentry(&stm, zip, argv[i]);
if (error)
die(error);
n = fz_readall(&buf, stm);
if (n < 0)
die(fz_ioerror(stm));
fz_dropstream(stm);
fwrite(buf->rp, 1, buf->wp - buf->rp, stdout);
fz_dropbuffer(buf);
}
sa_closezip(zip);
return 0;
}
int runxml(int argc, char **argv)
{
fz_error *error;
fz_stream *file;
sa_xmlparser *parser;
sa_xmlitem *item;
error = fz_openrfile(&file, argv[1]);
if (error)
die(error);
error = sa_openxml(&parser, file, 0);
if (error)
die(error);
item = sa_xmlnext(parser);
if (item)
sa_debugxml(item, 0);
sa_closexml(parser);
fz_dropstream(file);
return 0;
}
extern fz_error *sa_readtiff(fz_stream *);
int runtiff(int argc, char **argv)
{
fz_error *error;
fz_stream *file;
error = fz_openrfile(&file, argv[1]);
if (error)
die(error);
error = sa_readtiff(file);
if (error)
die(error);
fz_dropstream(file);
return 0;
}
int main(int argc, char **argv)
{
if (argc >= 2)
{
if (strstr(argv[1], "zip"))
return runzip(argc, argv);
if (strstr(argv[1], "xml"))
return runxml(argc, argv);
if (strstr(argv[1], "tif"))
return runtiff(argc, argv);
return runpack(argc, argv);
}
fprintf(stderr, "usage: samshow <file>\n");
fprintf(stderr, "usage: samshow <zipfile> <partname>\n");
fprintf(stderr, "usage: samshow <package> <partname>\n");
return 1;
}

View file

@ -1,29 +0,0 @@
#define gs_l_xbm_width 48
#define gs_l_xbm_height 48
#define gs_l_xbm_x_hot 0
#define gs_l_xbm_y_hot 0
static unsigned char gs_l_xbm_bits[] = {
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x07, 0x00,
0x00, 0xe0, 0xff, 0x0f, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x81, 0x07, 0x00,
0x00, 0xfc, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0xfe, 0x07, 0xf0, 0x1f, 0x00,
0x00, 0xff, 0x01, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0x41, 0xfc, 0x3f, 0x00,
0x80, 0xff, 0xc8, 0xfc, 0x3f, 0x00, 0x80, 0xff, 0xd8, 0xf8, 0x3f, 0x00,
0x80, 0xff, 0x98, 0xf0, 0x3f, 0x00, 0x80, 0xff, 0x10, 0xe0, 0x3f, 0x00,
0x00, 0xff, 0x01, 0xc0, 0x3f, 0x00, 0x00, 0xff, 0x81, 0x81, 0x1f, 0x00,
0x00, 0xfe, 0x83, 0x83, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x83, 0x0f, 0x00,
0x00, 0xf8, 0x1f, 0xc3, 0x03, 0x00, 0x00, 0xe0, 0x1f, 0xe0, 0x01, 0x00,
0x00, 0xf0, 0x1f, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00,
0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00,
0xc0, 0xff, 0xff, 0xff, 0x01, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00,
0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x03,
0x00, 0xc0, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x03,
0xc0, 0x3f, 0x00, 0x00, 0xff, 0x03, 0xe0, 0x0f, 0x00, 0x00, 0xfe, 0x03,
0xf0, 0x07, 0xfc, 0x00, 0xfc, 0x01, 0xf0, 0x07, 0x0e, 0x00, 0xff, 0x04,
0xf0, 0x07, 0x7e, 0xe0, 0x7f, 0x02, 0xf0, 0x0f, 0xfc, 0xff, 0x1f, 0x01,
0xe0, 0x1f, 0xf0, 0xff, 0xc3, 0x00, 0xc0, 0xff, 0x00, 0x00, 0x78, 0x00,
0x80, 0xff, 0x0f, 0xf8, 0x3f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0x00,
0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

View file

@ -1,511 +0,0 @@
#include "fitz.h"
#include "mupdf.h"
#include "pdfapp.h"
#include "gs_l.xbm"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
extern int ximage_init(Display *display, int screen, Visual *visual);
extern int ximage_get_depth(void);
extern Visual *ximage_get_visual(void);
extern Colormap ximage_get_colormap(void);
extern void ximage_blit(Drawable d, GC gc, int dstx, int dsty,
unsigned char *srcdata,
int srcx, int srcy, int srcw, int srch, int srcstride);
static Display *xdpy;
static Atom XA_TARGETS;
static Atom XA_TIMESTAMP;
static Atom XA_UTF8_STRING;
static int xscr;
static Window xwin;
static GC xgc;
static XEvent xevt;
static int mapped = 0;
static Cursor xcarrow, xchand, xcwait;
static int justcopied = 0;
static int dirty = 0;
static char *password = "";
static XColor xbgcolor;
static XColor xshcolor;
static int reqw = 0;
static int reqh = 0;
static char copylatin1[1024 * 16] = "";
static char copyutf8[1024 * 48] = "";
static Time copytime;
static pdfapp_t gapp;
/*
* Dialog boxes
*/
void winwarn(pdfapp_t *app, char *msg)
{
fprintf(stderr, "apparition: %s\n", msg);
}
void winerror(pdfapp_t *app, char *msg)
{
fprintf(stderr, "apparition: %s\n", msg);
exit(1);
}
char *winpassword(pdfapp_t *app, char *filename)
{
char *r = password;
password = NULL;
return r;
}
/*
* X11 magic
*/
void winopen(void)
{
XWMHints *hints;
xdpy = XOpenDisplay(nil);
if (!xdpy)
winerror(&gapp, "could not open display.");
XA_TARGETS = XInternAtom(xdpy, "TARGETS", False);
XA_TIMESTAMP = XInternAtom(xdpy, "TIMESTAMP", False);
XA_UTF8_STRING = XInternAtom(xdpy, "UTF8_STRING", False);
xscr = DefaultScreen(xdpy);
ximage_init(xdpy, xscr, DefaultVisual(xdpy, xscr));
xcarrow = XCreateFontCursor(xdpy, XC_left_ptr);
xchand = XCreateFontCursor(xdpy, XC_hand2);
xcwait = XCreateFontCursor(xdpy, XC_watch);
xbgcolor.red = 0x7000;
xbgcolor.green = 0x7000;
xbgcolor.blue = 0x7000;
xshcolor.red = 0x4000;
xshcolor.green = 0x4000;
xshcolor.blue = 0x4000;
XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xbgcolor);
XAllocColor(xdpy, DefaultColormap(xdpy, xscr), &xshcolor);
xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy),
10, 10, 200, 100, 1,
ximage_get_depth(),
InputOutput,
ximage_get_visual(),
0,
nil);
XSetWindowColormap(xdpy, xwin, ximage_get_colormap());
XSelectInput(xdpy, xwin,
StructureNotifyMask | ExposureMask | KeyPressMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
mapped = 0;
xgc = XCreateGC(xdpy, xwin, 0, nil);
XDefineCursor(xdpy, xwin, xcarrow);
hints = XAllocWMHints();
if (hints)
{
hints->flags = IconPixmapHint;
hints->icon_pixmap = XCreateBitmapFromData(xdpy, xwin,
gs_l_xbm_bits, gs_l_xbm_width, gs_l_xbm_height);
if (hints->icon_pixmap)
{
XSetWMHints(xdpy, xwin, hints);
}
XFree(hints);
}
}
void wincursor(pdfapp_t *app, int curs)
{
if (curs == ARROW)
XDefineCursor(xdpy, xwin, xcarrow);
if (curs == HAND)
XDefineCursor(xdpy, xwin, xchand);
if (curs == WAIT)
XDefineCursor(xdpy, xwin, xcwait);
XFlush(xdpy);
}
void wintitle(pdfapp_t *app, char *s)
{
#ifdef X_HAVE_UTF8_STRING
Xutf8SetWMProperties(xdpy, xwin, s, s, 0, 0, 0, 0, 0);
#else
XmbSetWMProperties(xdpy, xwin, s, s, 0, 0, 0, 0, 0);
#endif
}
void winconvert(pdfapp_t *app, fz_pixmap *image)
{
// never mind
}
void winresize(pdfapp_t *app, int w, int h)
{
XWindowChanges values;
int mask;
mask = CWWidth | CWHeight;
values.width = w;
values.height = h;
XConfigureWindow(xdpy, xwin, mask, &values);
reqw = w;
reqh = h;
if (!mapped)
{
gapp.winw = w;
gapp.winh = h;
XMapWindow(xdpy, xwin);
XFlush(xdpy);
while (1)
{
XNextEvent(xdpy, &xevt);
if (xevt.type == MapNotify)
break;
}
XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr));
XFillRectangle(xdpy, xwin, xgc, 0, 0, gapp.image->w, gapp.image->h);
XFlush(xdpy);
mapped = 1;
}
}
static void fillrect(int x, int y, int w, int h)
{
if (w > 0 && h > 0)
XFillRectangle(xdpy, xwin, xgc, x, y, w, h);
}
static void invertcopyrect()
{
unsigned t, *p;
int x, y;
int x0 = gapp.selr.x0 - gapp.panx;
int x1 = gapp.selr.x1 - gapp.panx;
int y0 = gapp.selr.y0 - gapp.pany;
int y1 = gapp.selr.y1 - gapp.pany;
x0 = CLAMP(x0, 0, gapp.image->w - 1);
x1 = CLAMP(x1, 0, gapp.image->w - 1);
y0 = CLAMP(y0, 0, gapp.image->h - 1);
y1 = CLAMP(y1, 0, gapp.image->h - 1);
for (y = y0; y < y1; y++)
{
p = (unsigned *)(gapp.image->samples + (y * gapp.image->w + x0) * 4);
for (x = x0; x < x1; x++)
{
*p = ~0 - *p;
p ++;
}
}
justcopied = 1;
}
void winblit(pdfapp_t *app)
{
int x0 = gapp.panx;
int y0 = gapp.pany;
int x1 = gapp.panx + gapp.image->w;
int y1 = gapp.pany + gapp.image->h;
XSetForeground(xdpy, xgc, xbgcolor.pixel);
fillrect(0, 0, x0, gapp.winh);
fillrect(x1, 0, gapp.winw - x1, gapp.winh);
fillrect(0, 0, gapp.winw, y0);
fillrect(0, y1, gapp.winw, gapp.winh - y1);
XSetForeground(xdpy, xgc, xshcolor.pixel);
fillrect(x0+2, y1, gapp.image->w, 2);
fillrect(x1, y0+2, 2, gapp.image->h);
if (gapp.iscopying || justcopied)
invertcopyrect();
ximage_blit(xwin, xgc,
x0, y0,
gapp.image->samples,
0, 0,
gapp.image->w,
gapp.image->h,
gapp.image->w * gapp.image->n);
if (gapp.iscopying || justcopied)
invertcopyrect();
}
void winrepaint(pdfapp_t *app)
{
dirty = 1;
}
void windocopy(pdfapp_t *app)
{
unsigned short copyucs2[16 * 1024];
char *latin1 = copylatin1;
char *utf8 = copyutf8;
unsigned short *ucs2;
int ucs;
pdfapp_oncopy(&gapp, copyucs2, 16 * 1024);
for (ucs2 = copyucs2; ucs2[0] != 0; ucs2++)
{
ucs = ucs2[0];
utf8 += runetochar(utf8, &ucs);
if (ucs < 256)
*latin1++ = ucs;
else
*latin1++ = '?';
}
*utf8 = 0;
*latin1 = 0;
printf("oncopy utf8=%d latin1=%d\n", strlen(copyutf8), strlen(copylatin1));
XSetSelectionOwner(xdpy, XA_PRIMARY, xwin, copytime);
justcopied = 1;
}
void onselreq(Window requestor, Atom selection, Atom target, Atom property, Time time)
{
XEvent nevt;
printf("onselreq\n");
if (property == None)
property = target;
nevt.xselection.type = SelectionNotify;
nevt.xselection.send_event = True;
nevt.xselection.display = xdpy;
nevt.xselection.requestor = requestor;
nevt.xselection.selection = selection;
nevt.xselection.target = target;
nevt.xselection.property = property;
nevt.xselection.time = time;
if (target == XA_TARGETS)
{
Atom atomlist[4];
atomlist[0] = XA_TARGETS;
atomlist[1] = XA_TIMESTAMP;
atomlist[2] = XA_STRING;
atomlist[3] = XA_UTF8_STRING;
printf(" -> targets\n");
XChangeProperty(xdpy, requestor, property, target,
32, PropModeReplace,
(unsigned char *)atomlist, sizeof(atomlist)/sizeof(Atom));
}
else if (target == XA_STRING)
{
printf(" -> string %d\n", strlen(copylatin1));
XChangeProperty(xdpy, requestor, property, target,
8, PropModeReplace,
(unsigned char *)copylatin1, strlen(copylatin1));
}
else if (target == XA_UTF8_STRING)
{
printf(" -> utf8string\n");
XChangeProperty(xdpy, requestor, property, target,
8, PropModeReplace,
(unsigned char *)copyutf8, strlen(copyutf8));
}
else
{
printf(" -> unknown\n");
nevt.xselection.property = None;
}
XSendEvent(xdpy, requestor, False, SelectionNotify, &nevt);
}
void winopenuri(pdfapp_t *app, char *buf)
{
char cmd[2048];
if (getenv("BROWSER"))
sprintf(cmd, "$BROWSER %s &", buf);
else
sprintf(cmd, "open %s", buf);
system(cmd);
}
void onkey(int c)
{
if (justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
if (c == 'q')
exit(0);
pdfapp_onkey(&gapp, c);
}
void onmouse(int x, int y, int btn, int modifiers, int state)
{
if (state != 0 && justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
pdfapp_onmouse(&gapp, x, y, btn, modifiers, state);
}
void usage(void)
{
fprintf(stderr, "usage: apparition [-d password] [-z zoom] [-p pagenumber] file.pdf\n");
exit(1);
}
int main(int argc, char **argv)
{
char *filename;
int c;
int len;
unsigned char buf[128];
KeySym keysym;
int oldx = 0;
int oldy = 0;
double zoom = 1.0;
int pageno = 1;
while ((c = getopt(argc, argv, "d:z:p:")) != -1)
{
switch (c)
{
case 'd': password = optarg; break;
case 'z': zoom = atof(optarg); break;
case 'p': pageno = atoi(optarg); break;
default: usage();
}
}
if (argc - optind == 0)
usage();
filename = argv[optind++];
fz_cpudetect();
fz_accelerate();
winopen();
pdfapp_init(&gapp);
gapp.scrw = DisplayWidth(xdpy, xscr);
gapp.scrh = DisplayHeight(xdpy, xscr);
gapp.zoom = zoom;
gapp.pageno = pageno;
pdfapp_open(&gapp, filename);
while (1)
{
do
{
XNextEvent(xdpy, &xevt);
switch (xevt.type)
{
case Expose:
dirty = 1;
break;
case ConfigureNotify:
if (gapp.image)
{
if (xevt.xconfigure.width != reqw ||
xevt.xconfigure.height != reqh)
gapp.shrinkwrap = 0;
}
pdfapp_onresize(&gapp,
xevt.xconfigure.width,
xevt.xconfigure.height);
break;
case KeyPress:
len = XLookupString(&xevt.xkey, buf, sizeof buf, &keysym, 0);
if (len)
onkey(buf[0]);
onmouse(oldx, oldy, 0, 0, 0);
if (dirty)
{
winblit(&gapp);
dirty = 0;
}
break;
case MotionNotify:
oldx = xevt.xbutton.x;
oldy = xevt.xbutton.y;
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 0);
break;
case ButtonPress:
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 1);
break;
case ButtonRelease:
copytime = xevt.xbutton.time;
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, -1);
break;
case SelectionRequest:
onselreq(xevt.xselectionrequest.requestor,
xevt.xselectionrequest.selection,
xevt.xselectionrequest.target,
xevt.xselectionrequest.property,
xevt.xselectionrequest.time);
break;
}
}
while (XPending(xdpy));
if (dirty)
{
winblit(&gapp);
dirty = 0;
}
}
pdfapp_close(&gapp);
return 0;
}

View file

@ -1,672 +0,0 @@
/*
* Blit ARGB images to X with X(Shm)Images
*/
#include <fitz.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
extern int ffs(int);
typedef void (*ximage_convert_func_t)
(
const unsigned char *src,
int srcstride,
unsigned char *dst,
int dststride,
int w,
int h
);
#define POOLSIZE 4
#define WIDTH 256
#define HEIGHT 256
enum {
ARGB8888,
BGRA8888,
RGBA8888,
ABGR8888,
RGB888,
BGR888,
RGB565,
RGB565_BR,
RGB555,
RGB555_BR,
BGR233,
UNKNOWN
};
static char *modename[] = {
"ARGB8888",
"BGRA8888",
"RGBA8888",
"ABGR8888",
"RGB888",
"BGR888",
"RGB565",
"RGB565_BR",
"RGB555",
"RGB555_BR",
"BGR233",
"UNKNOWN"
};
extern ximage_convert_func_t ximage_convert_funcs[];
static struct
{
Display *display;
int screen;
XVisualInfo visual;
Colormap colormap;
int bitsperpixel;
int mode;
XColor rgbcube[256];
ximage_convert_func_t convert_func;
int useshm;
XImage *pool[POOLSIZE];
/* MUST exist during the lifetime of the shared ximage according to the
xc/doc/hardcopy/Xext/mit-shm.PS.gz */
XShmSegmentInfo shminfo[POOLSIZE];
int lastused;
} info;
static XImage *
createximage(Display *dpy, Visual *vis, XShmSegmentInfo *xsi, int depth, int w, int h)
{
XImage *img;
Status status;
if (!XShmQueryExtension(dpy)) goto fallback;
img = XShmCreateImage(dpy, vis, depth, ZPixmap, nil, xsi, w, h);
if (!img)
{
fprintf(stderr, "warn: could not XShmCreateImage\n");
goto fallback;
}
xsi->shmid = shmget(IPC_PRIVATE,
img->bytes_per_line * img->height,
IPC_CREAT | 0777);
if (xsi->shmid < 0)
{
XDestroyImage(img);
fprintf(stderr, "warn: could not shmget\n");
goto fallback;
}
img->data = xsi->shmaddr = shmat(xsi->shmid, 0, 0);
if (img->data == (char*)-1)
{
XDestroyImage(img);
fprintf(stderr, "warn: could not shmat\n");
goto fallback;
}
xsi->readOnly = False;
status = XShmAttach(dpy, xsi);
if (!status)
{
shmdt(xsi->shmaddr);
XDestroyImage(img);
fprintf(stderr, "warn: could not XShmAttach\n");
goto fallback;
}
XSync(dpy, False);
shmctl(xsi->shmid, IPC_RMID, 0);
return img;
fallback:
info.useshm = 0;
img = XCreateImage(dpy, vis, depth, ZPixmap, 0, 0, w, h, 32, 0);
if (!img)
{
fprintf(stderr, "fail: could not XCreateImage");
abort();
}
img->data = malloc(h * img->bytes_per_line);
if (!img->data)
{
fprintf(stderr, "fail: could not malloc");
abort();
}
return img;
}
static void
make_colormap(void)
{
if (info.visual.class == PseudoColor && info.visual.depth == 8)
{
int i, r, g, b;
i = 0;
for (b = 0; b < 4; b++) {
for (g = 0; g < 8; g++) {
for (r = 0; r < 8; r++) {
info.rgbcube[i].pixel = i;
info.rgbcube[i].red = (r * 36) << 8;
info.rgbcube[i].green = (g * 36) << 8;
info.rgbcube[i].blue = (b * 85) << 8;
info.rgbcube[i].flags =
DoRed | DoGreen | DoBlue;
i++;
}
}
}
info.colormap = XCreateColormap(info.display,
RootWindow(info.display, info.screen),
info.visual.visual,
AllocAll);
XStoreColors(info.display, info.colormap, info.rgbcube, 256);
return;
}
else if (info.visual.class == TrueColor)
{
info.colormap = 0;
return;
}
fprintf(stderr, "Cannot handle visual class %d with depth: %d\n",
info.visual.class, info.visual.depth);
return;
}
static void
select_mode(void)
{
int byteorder;
int byterev;
unsigned long rm, gm, bm;
unsigned long rs, gs, bs;
byteorder = ImageByteOrder(info.display);
#if BYTE_ORDER == BIG_ENDIAN
byterev = byteorder != MSBFirst;
#else
byterev = byteorder != LSBFirst;
#endif
rm = info.visual.red_mask;
gm = info.visual.green_mask;
bm = info.visual.blue_mask;
rs = ffs(rm) - 1;
gs = ffs(gm) - 1;
bs = ffs(bm) - 1;
printf("ximage: mode %d/%d %08lx %08lx %08lx (%ld,%ld,%ld) %s%s\n",
info.visual.depth,
info.bitsperpixel,
rm, gm, bm, rs, gs, bs,
byteorder == MSBFirst ? "msb" : "lsb",
byterev ? " <swap>":"");
info.mode = UNKNOWN;
if (info.bitsperpixel == 8) {
/* Either PseudoColor with BGR233 colormap, or TrueColor */
info.mode = BGR233;
}
else if (info.bitsperpixel == 16) {
if (rm == 0xF800 && gm == 0x07E0 && bm == 0x001F)
info.mode = !byterev ? RGB565 : RGB565_BR;
if (rm == 0x7C00 && gm == 0x03E0 && bm == 0x001F)
info.mode = !byterev ? RGB555 : RGB555_BR;
}
else if (info.bitsperpixel == 24) {
if (rs == 0 && gs == 8 && bs == 16)
info.mode = byteorder == MSBFirst ? RGB888 : BGR888;
if (rs == 16 && gs == 8 && bs == 0)
info.mode = byteorder == MSBFirst ? BGR888 : RGB888;
}
else if (info.bitsperpixel == 32) {
if (rs == 0 && gs == 8 && bs == 16)
info.mode = byteorder == MSBFirst ? ABGR8888 : RGBA8888;
if (rs == 8 && gs == 16 && bs == 24)
info.mode = byteorder == MSBFirst ? BGRA8888 : ARGB8888;
if (rs == 16 && gs == 8 && bs == 0)
info.mode = byteorder == MSBFirst ? ARGB8888 : BGRA8888;
if (rs == 24 && gs == 16 && bs == 8)
info.mode = byteorder == MSBFirst ? RGBA8888 : ABGR8888;
}
printf("ximage: ARGB8888 to %s\n", modename[info.mode]);
/* select conversion function */
info.convert_func = ximage_convert_funcs[info.mode];
}
static int
create_pool(void)
{
int i;
info.lastused = 0;
for (i = 0; i < POOLSIZE; i++) {
info.pool[i] = nil;
}
for (i = 0; i < POOLSIZE; i++) {
info.pool[i] = createximage(info.display,
info.visual.visual, &info.shminfo[i], info.visual.depth,
WIDTH, HEIGHT);
if (info.pool[i] == nil) {
return 0;
}
}
return 1;
}
static XImage *
next_pool_image(void)
{
if (info.lastused + 1 >= POOLSIZE) {
if (info.useshm)
XSync(info.display, False);
else
XFlush(info.display);
info.lastused = 0;
}
return info.pool[info.lastused ++];
}
int
ximage_init(Display *display, int screen, Visual *visual)
{
XVisualInfo template;
XVisualInfo *visuals;
int nvisuals;
XPixmapFormatValues *formats;
int nformats;
int ok;
int i;
info.display = display;
info.screen = screen;
info.colormap = 0;
/* Get XVisualInfo for this visual */
template.visualid = XVisualIDFromVisual(visual);
visuals = XGetVisualInfo(display, VisualIDMask, &template, &nvisuals);
if (nvisuals != 1) {
fprintf(stderr, "Visual not found!\n");
XFree(visuals);
return 0;
}
memcpy(&info.visual, visuals, sizeof (XVisualInfo));
XFree(visuals);
/* Get appropriate PixmapFormat for this visual */
formats = XListPixmapFormats(info.display, &nformats);
for (i = 0; i < nformats; i++) {
if (formats[i].depth == info.visual.depth) {
info.bitsperpixel = formats[i].bits_per_pixel;
break;
}
}
XFree(formats);
if (i == nformats) {
fprintf(stderr, "PixmapFormat not found!\n");
return 0;
}
/* extract mode */
select_mode();
/* prepare colormap */
make_colormap();
/* prepare pool of XImages */
info.useshm = 1;
ok = create_pool();
if (!ok)
return 0;
printf("ximage: %sPutImage\n", info.useshm ? "XShm" : "X");
return 1;
}
int
ximage_get_depth(void)
{
return info.visual.depth;
}
Visual *
ximage_get_visual(void)
{
return info.visual.visual;
}
Colormap
ximage_get_colormap(void)
{
return info.colormap;
}
void
ximage_blit(Drawable d, GC gc,
int dstx, int dsty,
unsigned char *srcdata,
int srcx, int srcy,
int srcw, int srch,
int srcstride)
{
XImage *image;
int ax, ay;
int w, h;
unsigned char *srcptr;
for (ay = 0; ay < srch; ay += HEIGHT)
{
h = MIN(srch - ay, HEIGHT);
for (ax = 0; ax < srcw; ax += WIDTH)
{
w = MIN(srcw - ax, WIDTH);
image = next_pool_image();
srcptr = srcdata +
(ay + srcy) * srcstride +
(ax + srcx) * 4;
info.convert_func(srcptr, srcstride,
image->data,
image->bytes_per_line, w, h);
if (info.useshm)
{
XShmPutImage(info.display, d, gc, image,
0, 0, dstx + ax, dsty + ay,
w, h, False);
}
else
{
XPutImage(info.display, d, gc, image,
0, 0,
dstx + ax,
dsty + ay,
w, h);
}
}
}
}
/*
* Primitive conversion functions
*/
#ifndef restrict
#ifndef _C99
#ifdef __GNUC__
#define restrict __restrict__
#else
#define restrict
#endif
#endif
#endif
#define PARAMS \
const unsigned char * restrict src, \
int srcstride, \
unsigned char * restrict dst, \
int dststride, \
int w, \
int h
/*
* Convert byte:ARGB8888 to various formats
*/
static void
ximage_convert_argb8888(PARAMS)
{
int x, y;
unsigned * restrict s = (unsigned * restrict )src;
unsigned * restrict d = (unsigned * restrict )dst;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
d[x] = s[x];
}
d += dststride>>2;
s += srcstride>>2;
}
}
static void
ximage_convert_bgra8888(PARAMS)
{
int x, y;
unsigned *s = (unsigned *)src;
unsigned *d = (unsigned *)dst;
unsigned val;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
val = s[x];
d[x] =
(val >> 24) |
((val >> 8) & 0xff00) |
(val << 24) |
((val << 8) & 0xff0000);
/*
d[x] =
(((val >> 24) & 0xff) << 0) |
(((val >> 16) & 0xff) << 8) |
(((val >> 8) & 0xff) << 16) |
(((val >> 0) & 0xff) << 24);
*/
}
d += dststride>>2;
s += srcstride>>2;
}
}
/* following have yet to recieve some MMX love ;-) */
static void
ximage_convert_abgr8888(PARAMS)
{
int x, y;
unsigned *s = (unsigned *)src;
unsigned *d = (unsigned *)dst;
unsigned val;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
val = s[x];
#if 1 /* FZ_MSB */
d[x] = (val & 0xff00ff00) |
(((val << 16) | (val >> 16)) & 0x00ff00ff);
#else /* FZ_LSB */
d[x] = (val << 24) | ((val >> 8) & 0xff);
#endif
}
d += dststride>>2;
s += srcstride>>2;
}
}
static void
ximage_convert_rgba8888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[x * 4 + 0] = src[x * 4 + 1];
dst[x * 4 + 1] = src[x * 4 + 2];
dst[x * 4 + 2] = src[x * 4 + 3];
dst[x * 4 + 3] = src[x * 4 + 0];
}
dst += dststride;
src += srcstride;
}
}
static void
ximage_convert_bgr888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[3*x + 0] = src[4*x + 3];
dst[3*x + 1] = src[4*x + 2];
dst[3*x + 2] = src[4*x + 1];
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_rgb888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[3*x + 0] = src[4*x + 1];
dst[3*x + 1] = src[4*x + 2];
dst[3*x + 2] = src[4*x + 3];
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_rgb565(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 1];
g = src[4*x + 2];
b = src[4*x + 3];
((unsigned short *)dst)[x] =
((r & 0xF8) << 8) |
((g & 0xFC) << 3) |
(b >> 3);
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_rgb565_br(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 1];
g = src[4*x + 2];
b = src[4*x + 3];
/* final word is:
g4 g3 g2 b7 b6 b5 b4 b3 r7 r6 r5 r4 r3 g7 g6 g5
*/
((unsigned short *)dst)[x] =
(r & 0xF8) |
((g & 0xE0) >> 5) |
((g & 0x1C) << 11) |
((b & 0xF8) << 5);
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_rgb555(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 1];
g = src[4*x + 2];
b = src[4*x + 3];
((unsigned short *)dst)[x] =
((r & 0xF8) << 7) |
((g & 0xF8) << 2) |
(b >> 3);
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_rgb555_br(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 1];
g = src[4*x + 2];
b = src[4*x + 3];
/* final word is:
g5 g4 g3 b7 b6 b5 b4 b3 0 r7 r6 r5 r4 r3 g7 g6
*/
((unsigned short *)dst)[x] =
((r & 0xF8) >> 1) |
((g & 0xC0) >> 6) |
((g & 0x38) << 10) |
((b & 0xF8) << 5);
}
src += srcstride;
dst += dststride;
}
}
static void
ximage_convert_bgr233(PARAMS)
{
unsigned char r, g, b;
int x,y;
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
r = src[4*x + 1];
g = src[4*x + 2];
b = src[4*x + 3];
/* format: b7 b6 g7 g6 g5 r7 r6 r5 */
dst[x] = (b&0xC0) | ((g>>2)&0x38) | ((r>>5)&0x7);
}
src += srcstride;
dst += dststride;
}
}
ximage_convert_func_t ximage_convert_funcs[] = {
ximage_convert_argb8888,
ximage_convert_bgra8888,
ximage_convert_rgba8888,
ximage_convert_abgr8888,
ximage_convert_rgb888,
ximage_convert_bgr888,
ximage_convert_rgb565,
ximage_convert_rgb565_br,
ximage_convert_rgb555,
ximage_convert_rgb555_br,
ximage_convert_bgr233,
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,821 +0,0 @@
#include <fitz.h>
#include <mupdf.h>
#include "pdfapp.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <shellapi.h>
#define ID_ABOUT 0x1000
#define ID_DOCINFO 0x1001
static HWND hwndframe = NULL;
static HWND hwndview = NULL;
static HDC hdc;
static HBRUSH bgbrush;
static HBRUSH shbrush;
static BITMAPINFO *dibinf;
static HCURSOR arrowcurs, handcurs, waitcurs;
static LRESULT CALLBACK frameproc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK viewproc(HWND, UINT, WPARAM, LPARAM);
static int bmpstride = 0;
static char *bmpdata = NULL;
static int justcopied = 0;
static pdfapp_t gapp;
/*
* Associate Apparition with PDF files.
*/
void associate(char *argv0)
{
char tmp[256];
char *name = "Adobe PDF Document";
HKEY key, kicon, kshell, kopen, kcmd;
DWORD disp;
/* HKEY_CLASSES_ROOT\.pdf */
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
".pdf", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &key, &disp))
return;
if (RegSetValueEx(key, "", 0, REG_SZ, "Apparition", strlen("Apparition")+1))
return;
RegCloseKey(key);
/* HKEY_CLASSES_ROOT\Apparition */
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
"Apparition", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &key, &disp))
return;
if (RegSetValueEx(key, "", 0, REG_SZ, name, strlen(name)+1))
return;
/* HKEY_CLASSES_ROOT\Apparition\DefaultIcon */
if (RegCreateKeyEx(key,
"DefaultIcon", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &kicon, &disp))
return;
sprintf(tmp, "%s,1", argv0);
if (RegSetValueEx(kicon, "", 0, REG_SZ, tmp, strlen(tmp)+1))
return;
RegCloseKey(kicon);
/* HKEY_CLASSES_ROOT\Apparition\Shell\Open\Command */
if (RegCreateKeyEx(key,
"shell", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &kshell, &disp))
return;
if (RegCreateKeyEx(kshell,
"open", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &kopen, &disp))
return;
if (RegCreateKeyEx(kopen,
"command", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &kcmd, &disp))
return;
sprintf(tmp, "\"%s\" \"%%1\"", argv0);
if (RegSetValueEx(kcmd, "", 0, REG_SZ, tmp, strlen(tmp)+1))
return;
RegCloseKey(kcmd);
RegCloseKey(kopen);
RegCloseKey(kshell);
RegCloseKey(key);
}
/*
* Dialog boxes
*/
void winwarn(pdfapp_t *app, char *msg)
{
MessageBoxA(hwndframe, msg, "Apparition: Warning", MB_ICONWARNING);
}
void winerror(pdfapp_t *app, char *msg)
{
MessageBoxA(hwndframe, msg, "Apparition: Error", MB_ICONERROR);
exit(1);
}
int winfilename(char *buf, int len)
{
OPENFILENAME ofn;
strcpy(buf, "");
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwndframe;
ofn.lpstrFile = buf;
ofn.nMaxFile = len;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = "Apparition: Open PDF file";
ofn.lpstrFilter = "PDF Files (*.pdf)\0*.pdf\0All Files\0*\0\0";
ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
return GetOpenFileName(&ofn);
}
static char pd_filename[256] = "The file is encrypted.";
static char pd_password[256] = "";
static int pd_okay = 0;
INT CALLBACK
dlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
SetDlgItemText(hwnd, 4, pd_filename);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case 1:
pd_okay = 1;
GetDlgItemText(hwnd, 3, pd_password, sizeof pd_password);
EndDialog(hwnd, 0);
return TRUE;
case 2:
pd_okay = 0;
EndDialog(hwnd, 0);
return TRUE;
}
break;
}
return FALSE;
}
char *winpassword(pdfapp_t *app, char *filename)
{
char buf[124], *s;
strcpy(buf, filename);
s = buf;
if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1;
if (strrchr(s, '/')) s = strrchr(s, '/') + 1;
if (strlen(s) > 32)
strcpy(s + 30, "...");
sprintf(pd_filename, "The file \"%s\" is encrypted.", s);
DialogBox(NULL, "IDD_DLOGPASS", hwndframe, dlogpassproc);
if (pd_okay)
return pd_password;
return NULL;
}
INT CALLBACK
dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char buf[256];
pdf_xref *xref = gapp.xref;
fz_obj *obj;
switch(message)
{
case WM_INITDIALOG:
SetDlgItemTextA(hwnd, 0x10, gapp.filename);
sprintf(buf, "PDF %g", xref->version);
SetDlgItemTextA(hwnd, 0x11, buf);
if (xref->crypt)
{
sprintf(buf, "Standard %d bit RC4", xref->crypt->n * 8);
SetDlgItemTextA(hwnd, 0x12, buf);
strcpy(buf, "");
if (xref->crypt->p & (1 << 2))
strcat(buf, "print, ");
if (xref->crypt->p & (1 << 3))
strcat(buf, "modify, ");
if (xref->crypt->p & (1 << 4))
strcat(buf, "copy, ");
if (xref->crypt->p & (1 << 5))
strcat(buf, "annotate, ");
if (strlen(buf) > 2)
buf[strlen(buf)-2] = 0;
else
strcpy(buf, "none");
SetDlgItemTextA(hwnd, 0x13, buf);
}
else
{
SetDlgItemTextA(hwnd, 0x12, "None");
SetDlgItemTextA(hwnd, 0x13, "n/a");
}
if (!xref->info)
return TRUE;
#define SETUCS(ID) \
{ \
fz_error *error; \
unsigned short *ucs; \
error = pdf_toucs2(&ucs, obj); \
if (!error) \
{ \
SetDlgItemTextW(hwnd, ID, ucs); \
fz_free(ucs); \
} \
}
if ((obj = fz_dictgets(xref->info, "Title"))) SETUCS(0x20)
if ((obj = fz_dictgets(xref->info, "Author"))) SETUCS(0x21)
if ((obj = fz_dictgets(xref->info, "Subject"))) SETUCS(0x22)
if ((obj = fz_dictgets(xref->info, "Keywords"))) SETUCS(0x23)
if ((obj = fz_dictgets(xref->info, "Creator"))) SETUCS(0x24)
if ((obj = fz_dictgets(xref->info, "Producer"))) SETUCS(0x25)
if ((obj = fz_dictgets(xref->info, "CreationDate"))) SETUCS(0x26)
if ((obj = fz_dictgets(xref->info, "ModDate"))) SETUCS(0x27)
return TRUE;
case WM_COMMAND:
EndDialog(hwnd, 0);
return TRUE;
}
return FALSE;
}
void info()
{
DialogBox(NULL, "IDD_DLOGINFO", hwndframe, dloginfoproc);
}
INT CALLBACK
dlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
SetDlgItemTextA(hwnd, 0x10, gapp.filename);
SetDlgItemTextA(hwnd, 2, "Apparition is Copyright (C) 2006 artofcode, LLC");
SetDlgItemTextA(hwnd, 3, pdfapp_usage(&gapp));
return TRUE;
case WM_COMMAND:
EndDialog(hwnd, 0);
return TRUE;
}
return FALSE;
}
void help()
{
DialogBox(NULL, "IDD_DLOGABOUT", hwndframe, dlogaboutproc);
}
/*
* Main window
*/
void winopen()
{
WNDCLASS wc = {0};
HMENU menu;
RECT r;
ATOM atom;
/* Create and register window frame class */
wc.style = 0;
wc.lpfnWndProc = frameproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(wc.hInstance, "IDI_ICONAPP");
wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "FrameWindow";
atom = RegisterClass(&wc);
assert(atom && "Register window class");
/* Create and register window view class */
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = viewproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "ViewWindow";
atom = RegisterClass(&wc);
assert(atom && "Register window class");
/* Get screen size */
SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
gapp.scrw = r.right - r.left;
gapp.scrh = r.bottom - r.top;
/* Create cursors */
arrowcurs = LoadCursor(NULL, IDC_ARROW);
handcurs = LoadCursor(NULL, IDC_HAND);
waitcurs = LoadCursor(NULL, IDC_WAIT);
/* And a background color */
bgbrush = CreateSolidBrush(RGB(0x70,0x70,0x70));
shbrush = CreateSolidBrush(RGB(0x40,0x40,0x40));
/* Init DIB info for buffer */
dibinf = malloc(sizeof(BITMAPINFO) + 12);
assert(dibinf != NULL);
dibinf->bmiHeader.biSize = sizeof(dibinf->bmiHeader);
dibinf->bmiHeader.biPlanes = 1;
dibinf->bmiHeader.biBitCount = 24;
dibinf->bmiHeader.biCompression = BI_RGB;
dibinf->bmiHeader.biXPelsPerMeter = 2834;
dibinf->bmiHeader.biYPelsPerMeter = 2834;
dibinf->bmiHeader.biClrUsed = 0;
dibinf->bmiHeader.biClrImportant = 0;
dibinf->bmiHeader.biClrUsed = 0;
/* Create window */
hwndframe = CreateWindow("FrameWindow", // window class name
NULL, // window caption
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, // initial position
300, // initial x size
300, // initial y size
0, // parent window handle
0, // window menu handle
0, // program instance handle
0); // creation parameters
hwndview = CreateWindow("ViewWindow", // window class name
NULL,
WS_VISIBLE | WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hwndframe, 0, 0, 0);
hdc = NULL;
SetWindowTextA(hwndframe, "Apparition");
menu = GetSystemMenu(hwndframe, 0);
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
AppendMenu(menu, MF_STRING, ID_ABOUT, "About Apparition...");
AppendMenu(menu, MF_STRING, ID_DOCINFO, "Document Properties...");
SetCursor(arrowcurs);
}
void wincursor(pdfapp_t *app, int curs)
{
if (curs == ARROW)
SetCursor(arrowcurs);
if (curs == HAND)
SetCursor(handcurs);
if (curs == WAIT)
SetCursor(waitcurs);
}
void wintitle(pdfapp_t *app, char *title)
{
unsigned short wide[256], *dp;
char *sp;
int rune;
dp = wide;
sp = title;
while (*sp && dp < wide + 255)
{
sp += chartorune(&rune, sp);
*dp++ = rune;
}
*dp = 0;
SetWindowTextW(hwndframe, wide);
}
void winconvert(pdfapp_t *app, fz_pixmap *image)
{
int y, x;
if (bmpdata)
fz_free(bmpdata);
bmpstride = ((image->w * 3 + 3) / 4) * 4;
bmpdata = fz_malloc(image->h * bmpstride);
if (!bmpdata)
return;
for (y = 0; y < image->h; y++)
{
char *p = bmpdata + y * bmpstride;
char *s = image->samples + y * image->w * 4;
for (x = 0; x < image->w; x++)
{
p[x * 3 + 0] = s[x * 4 + 3];
p[x * 3 + 1] = s[x * 4 + 2];
p[x * 3 + 2] = s[x * 4 + 1];
}
}
}
void invertcopyrect(void)
{
unsigned char *p;
int x0 = gapp.selr.x0 - gapp.panx;
int x1 = gapp.selr.x1 - gapp.panx;
int y0 = gapp.selr.y0 - gapp.pany;
int y1 = gapp.selr.y1 - gapp.pany;
int x, y;
x0 = CLAMP(x0, 0, gapp.image->w - 1);
x1 = CLAMP(x1, 0, gapp.image->w - 1);
y0 = CLAMP(y0, 0, gapp.image->h - 1);
y1 = CLAMP(y1, 0, gapp.image->h - 1);
for (y = y0; y < y1; y++)
{
p = bmpdata + y * bmpstride + x0 * 3;
for (x = x0; x < x1; x++)
{
p[0] = 255 - p[0];
p[1] = 255 - p[1];
p[2] = 255 - p[2];
p += 3;
}
}
justcopied = 1;
}
void winblit()
{
int x0 = gapp.panx;
int y0 = gapp.pany;
int x1 = gapp.panx + gapp.image->w;
int y1 = gapp.pany + gapp.image->h;
RECT r;
if (bmpdata)
{
if (gapp.iscopying || justcopied)
invertcopyrect();
dibinf->bmiHeader.biWidth = gapp.image->w;
dibinf->bmiHeader.biHeight = -gapp.image->h;
dibinf->bmiHeader.biSizeImage = gapp.image->h * bmpstride;
SetDIBitsToDevice(hdc,
gapp.panx, /* destx */
gapp.pany, /* desty */
gapp.image->w, /* destw */
gapp.image->h, /* desth */
0, /* srcx */
0, /* srcy */
0, /* startscan */
gapp.image->h, /* numscans */
bmpdata, /* pBits */
dibinf, /* pInfo */
DIB_RGB_COLORS /* color use flag */
);
if (gapp.iscopying || justcopied)
invertcopyrect();
}
/* Grey background */
r.top = 0; r.bottom = gapp.winh;
r.left = 0; r.right = x0;
FillRect(hdc, &r, bgbrush);
r.left = x1; r.right = gapp.winw;
FillRect(hdc, &r, bgbrush);
r.left = 0; r.right = gapp.winw;
r.top = 0; r.bottom = y0;
FillRect(hdc, &r, bgbrush);
r.top = y1; r.bottom = gapp.winh;
FillRect(hdc, &r, bgbrush);
/* Drop shadow */
r.left = x0 + 2;
r.right = x1 + 2;
r.top = y1;
r.bottom = y1 + 2;
FillRect(hdc, &r, shbrush);
r.left = x1;
r.right = x1 + 2;
r.top = y0 + 2;
r.bottom = y1;
FillRect(hdc, &r, shbrush);
}
void winresize(pdfapp_t *app, int w, int h)
{
ShowWindow(hwndframe, SW_SHOWDEFAULT);
w += GetSystemMetrics(SM_CXFRAME) * 2;
h += GetSystemMetrics(SM_CYFRAME) * 2;
h += GetSystemMetrics(SM_CYCAPTION);
SetWindowPos(hwndframe, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);
}
void winrepaint(pdfapp_t *app)
{
InvalidateRect(hwndview, NULL, 0);
}
/*
* Event handling
*/
void windocopy(pdfapp_t *app)
{
HGLOBAL handle;
unsigned short *ucsbuf;
if (!OpenClipboard(hwndframe))
return;
EmptyClipboard();
handle = GlobalAlloc(GMEM_MOVEABLE, 4096 * sizeof(unsigned short));
if (!handle)
{
CloseClipboard();
return;
}
ucsbuf = GlobalLock(handle);
pdfapp_oncopy(&gapp, ucsbuf, 4096);
GlobalUnlock(handle);
SetClipboardData(CF_UNICODETEXT, handle);
CloseClipboard();
justcopied = 1; /* keep inversion around for a while... */
}
void winopenuri(pdfapp_t *app, char *buf)
{
ShellExecute(hwndframe, "open", buf, 0, 0, SW_SHOWNORMAL);
}
void handlekey(int c)
{
if (GetCapture() == hwndview)
return;
if (justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
/* translate VK into ascii equivalents */
switch (c)
{
case VK_F1: c = '?'; break;
case VK_ESCAPE: c = 'q'; break;
case VK_DOWN: c = 'd'; break;
case VK_UP: c = 'u'; break;
case VK_LEFT: c = 'p'; break;
case VK_RIGHT: c = 'n'; break;
case VK_PRIOR: c = 'b'; break;
case VK_NEXT: c = ' '; break;
}
if (c == 'q')
exit(0);
else if (c == '?' || c == 'h')
help();
else
pdfapp_onkey(&gapp, c);
}
void handlemouse(int x, int y, int btn, int state)
{
if (state != 0 && justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
if (state == 1)
SetCapture(hwndview);
if (state == -1)
ReleaseCapture();
pdfapp_onmouse(&gapp, x, y, btn, 0, state);
}
LRESULT CALLBACK
frameproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SETFOCUS:
PostMessage(hwnd, WM_APP+5, 0, 0);
return 0;
case WM_APP+5:
SetFocus(hwndview);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SYSCOMMAND:
if (wParam == ID_ABOUT)
{
help();
return 0;
}
if (wParam == ID_DOCINFO)
{
info();
return 0;
}
break;
case WM_SIZE:
{
// More generally, you should use GetEffectiveClientRect
// if you have a toolbar etc.
RECT rect;
GetClientRect(hwnd, &rect);
MoveWindow(hwndview, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top, TRUE);
}
return 0;
case WM_SIZING:
gapp.shrinkwrap = 0;
break;
case WM_NOTIFY:
case WM_COMMAND:
return SendMessage(hwndview, message, wParam, lParam);
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK
viewproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int oldx = 0;
static int oldy = 0;
int x = (signed short) LOWORD(lParam);
int y = (signed short) HIWORD(lParam);
switch (message)
{
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
return 0;
if (wParam == SIZE_MAXIMIZED)
gapp.shrinkwrap = 0;
pdfapp_onresize(&gapp, LOWORD(lParam), HIWORD(lParam));
break;
/* Paint events are low priority and automagically catenated
* so we don't need to do any fancy waiting to defer repainting.
*/
case WM_PAINT:
{
//puts("WM_PAINT");
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
winblit();
hdc = NULL;
EndPaint(hwnd, &ps);
return 0;
}
case WM_ERASEBKGND:
return 1; // well, we don't need to erase to redraw cleanly
/* Mouse events */
case WM_LBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 1, 1);
return 0;
case WM_MBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 2, 1);
return 0;
case WM_RBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 3, 1);
return 0;
case WM_LBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 1, -1);
return 0;
case WM_MBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 2, -1);
return 0;
case WM_RBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 3, -1);
return 0;
case WM_MOUSEMOVE:
oldx = x; oldy = y;
handlemouse(x, y, 0, 0);
return 0;
/* Mouse wheel */
case WM_MOUSEWHEEL:
if ((signed short)HIWORD(wParam) > 0)
handlekey(LOWORD(wParam) & MK_SHIFT ? '+' : 'u');
else
handlekey(LOWORD(wParam) & MK_SHIFT ? '-' : 'd');
return 0;
/* Keyboard events */
case WM_KEYDOWN:
/* only handle special keys */
switch (wParam)
{
case VK_F1:
case VK_LEFT:
case VK_UP:
case VK_PRIOR:
case VK_RIGHT:
case VK_DOWN:
case VK_NEXT:
case VK_ESCAPE:
handlekey(wParam);
handlemouse(oldx, oldy, 0, 0); /* update cursor */
return 0;
}
return 1;
/* unicode encoded chars, including escape, backspace etc... */
case WM_CHAR:
handlekey(wParam);
handlemouse(oldx, oldy, 0, 0); /* update cursor */
return 0;
}
fflush(stdout);
/* Pass on unhandled events to Windows */
return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char **argv)
{
char buf[1024];
char *filename;
MSG msg;
fz_cpudetect();
fz_accelerate();
pdfapp_init(&gapp);
associate(argv[0]);
winopen();
if (argc == 2)
filename = strdup(argv[1]);
else
{
if (!winfilename(buf, sizeof buf))
exit(0);
filename = buf;
}
pdfapp_open(&gapp, filename);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
pdfapp_close(&gapp);
return 0;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char * argv[1] = {"mupdf.exe"};
int argc = 1;
main(argc, argv);
}

View file

@ -1,62 +0,0 @@
IDI_ICONAPP ICON "gsapp.ico"
IDI_ICONDOC ICON "gsdoc.ico"
IDD_DLOGPASS DIALOGEX 50, 50, 204, 60
//STYLE DS_MODALFRAME | WS_POPUP
STYLE 128 | 0x80000000
CAPTION " Apparition: Password "
FONT 8, "MS Shell Dlg"
BEGIN
EDITTEXT 3, 57,20,140,12, 32
DEFPUSHBUTTON "Okay", 1, 90,40,50,14, 0x50010001
PUSHBUTTON "Cancel", 2, 147,40,50,14, 0x50010000
LTEXT "The file is encrypted." 4, 10,7,180,10, 0x00000
LTEXT "Password:" 5, 17,22,40,10, 0x00000
END
IDD_DLOGINFO DIALOGEX 50, 50, 300, 145
STYLE 128 | 0x80000000
CAPTION " Document Properties "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Okay", 1, 300-10-50,145-7-14,50,14, 0x50010001
LTEXT "File:" -1, 10,10,50,10, 0
LTEXT "Format:" -1, 10,20,50,10, 0
LTEXT "Encryption:" -1, 10,30,50,10, 0
LTEXT "Permissions:" -1, 10,40,50,10, 0
LTEXT "<file" 0x10, 60,10,230,10, 0
LTEXT "<version" 0x11, 60,20,230,10, 0
LTEXT "<encryption" 0x12, 60,30,230,10, 0
LTEXT "<permissions" 0x13, 60,40,230,10, 0
LTEXT "Title:" -1, 10,55,50,10, 0
LTEXT "Author:" -1, 10,65,50,10, 0
LTEXT "Subject:" -1, 10,75,50,10, 0
LTEXT "Keywords:" -1, 10,85,50,10, 0
LTEXT "Creator:" -1, 10,95,50,10, 0
LTEXT "Producer:" -1, 10,105,50,10, 0
LTEXT "Created:" -1, 10,115,50,10, 0
LTEXT "Modified:" -1, 10,125,50,10, 0
LTEXT "" 0x20, 60,55,230,10, 0
LTEXT "" 0x21, 60,65,230,10, 0
LTEXT "" 0x22, 60,75,230,10, 0
LTEXT "" 0x23, 60,85,230,10, 0
LTEXT "" 0x24, 60,95,230,10, 0
LTEXT "" 0x25, 60,105,230,10, 0
LTEXT "" 0x26, 60,115,100,10, 0
LTEXT "" 0x27, 60,125,100,10, 0
END
IDD_DLOGABOUT DIALOGEX 50, 50, 200, 210
STYLE 128 | 0x80000000
CAPTION " About Apparition "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Okay", 1, 200-10-50,210-7-14,50,14, 0x50010001
LTEXT "<copyright>" 2, 10,10,180,10, 0
LTEXT "<usage>" 3, 10,25,180,160, 0
END

View file

@ -1,52 +0,0 @@
/*
* In place, rewrite name to compress multiple /, eliminate ., and process ..
*/
#define SEP(x) ((x)=='/' || (x) == 0)
char *
cleanname(char *name)
{
char *p, *q, *dotdot;
int rooted;
rooted = name[0] == '/';
/*
* invariants:
* p points at beginning of path element we're considering.
* q points just past the last path element we wrote (no slash).
* dotdot points just past the point where .. cannot backtrack
* any further (no slash).
*/
p = q = dotdot = name+rooted;
while(*p) {
if(p[0] == '/') /* null element */
p++;
else if(p[0] == '.' && SEP(p[1]))
p += 1; /* don't count the separator in case it is nul */
else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
p += 2;
if(q > dotdot) { /* can backtrack */
while(--q > dotdot && *q != '/')
;
} else if(!rooted) { /* /.. is / but ./../ is .. */
if(q != name)
*q++ = '/';
*q++ = '.';
*q++ = '.';
dotdot = q;
}
} else { /* real path element */
if(q != name+rooted)
*q++ = '/';
while((*q = *p) != '/' && *q != 0)
p++, q++;
}
}
if(q == name) /* empty string is really ``.'' */
*q++ = '.';
*q = '\0';
return name;
}

View file

@ -1,221 +0,0 @@
/*
run-time cpu feature detection code
mm, alphabet soup...
Glenn Kennard <d98gk@efd.lth.se>
*/
#include "fitz-base.h"
/* global run-time constant */
unsigned fz_cpuflags = 0;
#ifndef HAVE_CPUDEP
void fz_accelerate(void)
{
}
void fz_cpudetect(void)
{
}
#else
#include <signal.h> /* signal/sigaction */
#include <setjmp.h> /* sigsetjmp/siglongjmp */
#ifdef WIN32
#define sigjmp_buf jmp_buf
#define sigsetjmp(a,b) setjmp(a)
#define siglongjmp longjmp
#endif
typedef struct {
void (*test)(void);
const unsigned flag;
const char *name;
} featuretest;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
/* need emms?? */
static void mmx(void)
{ __asm__ ("pand %mm0, %mm0\n\t"); }
static void m3dnow(void)
{ __asm__ ("pavgusb %mm0, %mm0\n\t"); }
static void mmxext(void) /* aka Extended 3DNow! */
{ __asm__ ("pmaxsw %mm0, %mm0\n\t"); }
static void sse(void)
{ __asm__ ("andps %xmm0, %xmm0\n\t"); }
static void sse2(void)
{ __asm__ ("andpd %xmm0, %xmm0\n\t"); }
/* static void sse3(void) */
/* { __asm__ ("haddps %%xmm0, %%xmm0\n\t" : : : "%xmm0"); } */
#ifdef ARCH_X86_64
static void amd64(void)
{ __asm__ ("and %rax, %rax\n\t"); }
#endif
static const featuretest features[] = {
{ mmx, HAVE_MMX, "mmx" },
{ m3dnow, HAVE_3DNOW, "3dnow" },
{ mmxext, HAVE_MMXEXT, "mmxext" },
{ sse, HAVE_SSE, "sse" },
{ sse2, HAVE_SSE2, "sse2" },
/* { sse3, HAVE_SSE3, "sse3" }, */
#ifdef ARCH_X86_64
{ amd64, HAVE_AMD64, "amd64" }
#endif
};
#endif
#if defined(ARCH_SPARC)
/* assembler must have -xarch=v8plusa passed to it (v9a for 64 bit binaries) */
static void vis(void)
{ __asm__ ("fand %f8, %f8, %f8\n\t"); }
static const featuretest features[] = {
{ vis, HAVE_VIS, "vis" }
};
#endif
#if defined(ARCH_PPC)
static void altivec(void)
{ __asm__ ("vand v0, v0, v0\n\t"); }
static const featuretest features[] = {
{ altivec, HAVE_ALTIVEC, "altivec" },
};
#endif
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump;
static void
sigillhandler(int sig)
{
if (!canjump) {
signal(sig, SIG_DFL);
raise(sig);
}
canjump = 0;
siglongjmp(jmpbuf, 1);
}
static int
enabled(char *env, const char *ext)
{
int len;
char *s;
if (!env)
return 1;
len = strlen(ext);
while ((s = strstr(env, ext)))
{
s += len;
if (*s == ' ' || *s == ',' || *s == '\0')
return 1;
}
return 0;
}
static void
dumpflags(void)
{
unsigned f = fz_cpuflags;
int i, n;
fputs("detected cpu features:", stdout);
n = 0;
for (i = 0; i < sizeof(features) / sizeof(featuretest); i++)
{
if (f & features[i].flag)
{
fputc(' ', stdout);
fputs(features[i].name, stdout);
n ++;
}
}
if (!n)
fputs(" none", stdout);
fputc('\n', stdout);
}
void fz_cpudetect(void)
{
static int hasrun = 0;
unsigned flags = 0;
int i;
void (*oldhandler)(int) = NULL;
void (*tmphandler)(int);
char *env;
if (hasrun)
return;
hasrun = 1;
env = getenv("CPUACCEL");
for (i = 0; i < sizeof(features) / sizeof(featuretest); i++)
{
canjump = 0;
tmphandler = signal(SIGILL, sigillhandler);
if (!oldhandler)
oldhandler = tmphandler;
if (sigsetjmp(jmpbuf, 1))
{
/* test failed - disable feature */
flags &= ~features[i].flag;
continue;
}
canjump = 1;
features[i].test();
/* if we got here the test succeeded */
if (enabled(env, features[i].name))
flags |= features[i].flag;
else
flags &= ~features[i].flag;
}
/* restore previous signal handler */
signal(SIGILL, oldhandler);
fz_cpuflags = flags;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
__asm__ __volatile__ ("emms\n\t");
#endif
dumpflags();
}
static __attribute__((constructor, used)) void fzcpudetect(void)
{
fz_cpudetect();
}
#endif

View file

@ -1,74 +0,0 @@
#include "fitz-base.h"
void
fz_warn(char *fmt, ...)
{
va_list ap;
fprintf(stderr, "warning: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}
fz_error *
fz_throw1(char *fmt, ...)
{
va_list ap;
fz_error *eo;
eo = fz_malloc(sizeof(fz_error));
if (!eo) return fz_outofmem;
eo->refs = 1;
strlcpy(eo->func, "unknown", sizeof eo->func);
strlcpy(eo->file, "unknown", sizeof eo->file);
eo->line = 0;
va_start(ap, fmt);
vsnprintf(eo->msg, sizeof eo->msg, fmt, ap);
eo->msg[sizeof(eo->msg) - 1] = '\0';
va_end(ap);
return eo;
}
fz_error *
fz_throw0(const char *func, const char *file, int line, char *fmt, ...)
{
va_list ap;
fz_error *eo;
eo = fz_malloc(sizeof(fz_error));
if (!eo) return fz_outofmem;
eo->refs = 1;
strlcpy(eo->func, func, sizeof eo->func);
strlcpy(eo->file, file, sizeof eo->file);
eo->line = line;
va_start(ap, fmt);
vsnprintf(eo->msg, sizeof eo->msg, fmt, ap);
eo->msg[sizeof(eo->msg) - 1] = '\0';
va_end(ap);
if (getenv("BOMB"))
{
fflush(stdout);
fprintf(stderr, "%s:%d: %s(): %s\n", eo->file, eo->line, eo->func, eo->msg);
fflush(stderr);
abort();
}
return eo;
}
void
fz_droperror(fz_error *eo)
{
if (eo->refs > 0)
eo->refs--;
if (eo->refs == 0)
fz_free(eo);
}

View file

@ -1,274 +0,0 @@
/* Linear probe hash table.
* 2004 (C) Tor Andersson.
* BSD license.
*
* Simple hashtable with open adressing linear probe.
* Unlike text book examples, removing entries works
* correctly in this implementation so it wont start
* exhibiting bad behaviour if entries are inserted
* and removed frequently.
*/
#include "fitz-base.h"
enum { MAXKEYLEN = 16 };
typedef struct fz_hashentry_s fz_hashentry;
struct fz_hashentry_s
{
unsigned char key[MAXKEYLEN];
void *val;
};
struct fz_hashtable_s
{
int keylen;
int size;
int load;
fz_hashentry *ents;
};
static unsigned hash(unsigned char *s, int len)
{
unsigned hash = 0;
int i;
for (i = 0; i < len; i++)
{
hash += s[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
fz_error *
fz_newhash(fz_hashtable **tablep, int initialsize, int keylen)
{
fz_hashtable *table;
assert(keylen <= MAXKEYLEN);
table = *tablep = fz_malloc(sizeof(fz_hashtable));
if (!table)
return fz_outofmem;
table->keylen = keylen;
table->size = initialsize;
table->load = 0;
table->ents = fz_malloc(sizeof(fz_hashentry) * table->size);
if (!table->ents)
{
fz_free(table);
*tablep = nil;
return fz_outofmem;
}
memset(table->ents, 0, sizeof(fz_hashentry) * table->size);
return nil;
}
void
fz_emptyhash(fz_hashtable *table)
{
table->load = 0;
memset(table->ents, 0, sizeof(fz_hashentry) * table->size);
}
int
fz_hashlen(fz_hashtable *table)
{
return table->size;
}
void *
fz_hashgetkey(fz_hashtable *table, int idx)
{
return table->ents[idx].key;
}
void *
fz_hashgetval(fz_hashtable *table, int idx)
{
return table->ents[idx].val;
}
void
fz_drophash(fz_hashtable *table)
{
fz_free(table->ents);
fz_free(table);
}
fz_error *
fz_resizehash(fz_hashtable *table, int newsize)
{
fz_error *error;
fz_hashentry *newents;
fz_hashentry *oldents;
int oldload;
int oldsize;
int i;
oldsize = table->size;
oldload = table->load;
oldents = table->ents;
if (newsize < oldload * 8 / 10)
return fz_throw("rangecheck: resize hash too small");
newents = fz_malloc(sizeof(fz_hashentry) * newsize);
if (!newents)
return fz_outofmem;
table->size = newsize;
table->load = 0;
table->ents = newents;
memset(table->ents, 0, sizeof(fz_hashentry) * table->size);
for (i = 0; i < oldsize; i++)
{
if (oldents[i].val)
{
error = fz_hashinsert(table, oldents[i].key, oldents[i].val);
if (error)
{
table->size = oldsize;
table->load = oldload;
table->ents = oldents;
fz_free(newents);
return error;
}
}
}
fz_free(oldents);
return nil;
}
void *
fz_hashfind(fz_hashtable *table, void *key)
{
fz_hashentry *ents = table->ents;
unsigned size = table->size;
unsigned pos = hash(key, table->keylen) % size;
while (1)
{
if (!ents[pos].val)
return nil;
if (memcmp(key, &ents[pos].key, table->keylen) == 0)
return ents[pos].val;
pos = (pos + 1) % size;
}
}
fz_error *
fz_hashinsert(fz_hashtable *table, void *key, void *val)
{
fz_error *error;
fz_hashentry *ents;
unsigned size;
unsigned pos;
if (table->load > table->size * 8 / 10)
{
error = fz_resizehash(table, table->size * 2);
if (error)
return error;
}
ents = table->ents;
size = table->size;
pos = hash(key, table->keylen) % size;
while (1)
{
if (!ents[pos].val)
{
memcpy(ents[pos].key, key, table->keylen);
ents[pos].val = val;
table->load ++;
return nil;
}
if (memcmp(key, &ents[pos].key, table->keylen) == 0)
return fz_throw("rangecheck: overwrite hash slot");
pos = (pos + 1) % size;
}
return nil;
}
fz_error *
fz_hashremove(fz_hashtable *table, void *key)
{
fz_hashentry *ents = table->ents;
unsigned size = table->size;
unsigned pos = hash(key, table->keylen) % size;
unsigned hole, look, code;
while (1)
{
if (!ents[pos].val)
return fz_throw("rangecheck: remove inexistant hash entry");
if (memcmp(key, &ents[pos].key, table->keylen) == 0)
{
ents[pos].val = nil;
hole = pos;
look = (hole + 1) % size;
while (ents[look].val)
{
code = hash(ents[look].key, table->keylen) % size;
if ((code <= hole && hole < look) ||
(look < code && code <= hole) ||
(hole < look && look < code))
{
ents[hole] = ents[look];
ents[look].val = nil;
hole = look;
}
look = (look + 1) % size;
}
table->load --;
return nil;
}
pos = (pos + 1) % size;
}
}
void
fz_debughash(fz_hashtable *table)
{
int i, k;
printf("cache load %d / %d\n", table->load, table->size);
for (i = 0; i < table->size; i++)
{
if (!table->ents[i].val)
printf("table % 4d: empty\n", i);
else
{
printf("table % 4d: key=", i);
for (k = 0; k < MAXKEYLEN; k++)
printf("%02x", ((char*)table->ents[i].key)[k]);
printf(" val=$%p\n", table->ents[i].val);
}
}
}

View file

@ -1,151 +0,0 @@
#include "fitz-base.h"
void fz_invert3x3(float *dst, float *m)
{
float det;
int i;
#define M3(m,i,j) (m)[3*i+j]
#define D2(a,b,c,d) (a * d - b * c)
#define D3(a1,a2,a3,b1,b2,b3,c1,c2,c3) \
(a1 * D2(b2,b3,c2,c3)) - \
(b1 * D2(a2,a3,c2,c3)) + \
(c1 * D2(a2,a3,b2,b3))
det = D3(M3(m,0,0), M3(m,1,0), M3(m,2,0),
M3(m,0,1), M3(m,1,1), M3(m,2,1),
M3(m,0,2), M3(m,1,2), M3(m,2,2));
if (det == 0)
det = 1.0;
det = 1.0 / det;
M3(dst,0,0) = M3(m,1,1) * M3(m,2,2) - M3(m,1,2) * M3(m,2,1);
M3(dst,0,1) = -M3(m,0,1) * M3(m,2,2) + M3(m,0,2) * M3(m,2,1);
M3(dst,0,2) = M3(m,0,1) * M3(m,1,2) - M3(m,0,2) * M3(m,1,1);
M3(dst,1,0) = -M3(m,1,0) * M3(m,2,2) + M3(m,1,2) * M3(m,2,0);
M3(dst,1,1) = M3(m,0,0) * M3(m,2,2) - M3(m,0,2) * M3(m,2,0);
M3(dst,1,2) = -M3(m,0,0) * M3(m,1,2) + M3(m,0,2) * M3(m,1,0);
M3(dst,2,0) = M3(m,1,0) * M3(m,2,1) - M3(m,1,1) * M3(m,2,0);
M3(dst,2,1) = -M3(m,0,0) * M3(m,2,1) + M3(m,0,1) * M3(m,2,0);
M3(dst,2,2) = M3(m,0,0) * M3(m,1,1) - M3(m,0,1) * M3(m,1,0);
for (i = 0; i < 9; i++)
dst[i] *= det;
}
fz_matrix
fz_concat(fz_matrix one, fz_matrix two)
{
fz_matrix dst;
dst.a = one.a * two.a + one.b * two.c;
dst.b = one.a * two.b + one.b * two.d;
dst.c = one.c * two.a + one.d * two.c;
dst.d = one.c * two.b + one.d * two.d;
dst.e = one.e * two.a + one.f * two.c + two.e;
dst.f = one.e * two.b + one.f * two.d + two.f;
return dst;
}
fz_matrix
fz_identity(void)
{
fz_matrix m;
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = 0; m.f = 0;
return m;
}
fz_matrix
fz_scale(float sx, float sy)
{
fz_matrix m;
m.a = sx; m.b = 0;
m.c = 0; m.d = sy;
m.e = 0; m.f = 0;
return m;
}
fz_matrix
fz_rotate(float theta)
{
fz_matrix m;
float s = sin(theta * M_PI / 180.0);
float c = cos(theta * M_PI / 180.0);
m.a = c; m.b = s;
m.c = -s; m.d = c;
m.e = 0; m.f = 0;
return m;
}
fz_matrix
fz_translate(float tx, float ty)
{
fz_matrix m;
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = tx; m.f = ty;
return m;
}
fz_matrix
fz_invertmatrix(fz_matrix src)
{
fz_matrix dst;
float rdet = 1.0 / (src.a * src.d - src.b * src.c);
dst.a = src.d * rdet;
dst.b = -src.b * rdet;
dst.c = -src.c * rdet;
dst.d = src.a * rdet;
dst.e = -src.e * dst.a - src.f * dst.c;
dst.f = -src.e * dst.b - src.f * dst.d;
return dst;
}
int
fz_isrectilinear(fz_matrix m)
{
return (fabs(m.b) < FLT_EPSILON && fabs(m.c) < FLT_EPSILON) ||
(fabs(m.a) < FLT_EPSILON && fabs(m.d) < FLT_EPSILON);
}
float
fz_matrixexpansion(fz_matrix m)
{
return sqrt(fabs(m.a * m.d - m.b * m.c));
}
fz_point
fz_transformpoint(fz_matrix m, fz_point p)
{
fz_point t;
t.x = p.x * m.a + p.y * m.c + m.e;
t.y = p.x * m.b + p.y * m.d + m.f;
return t;
}
fz_rect
fz_transformaabb(fz_matrix m, fz_rect r)
{
fz_point s, t, u, v;
if (fz_isinfiniterect(r))
return r;
s.x = r.x0; s.y = r.y0;
t.x = r.x0; t.y = r.y1;
u.x = r.x1; u.y = r.y1;
v.x = r.x1; v.y = r.y0;
s = fz_transformpoint(m, s);
t = fz_transformpoint(m, t);
u = fz_transformpoint(m, u);
v = fz_transformpoint(m, v);
r.x0 = MIN4(s.x, t.x, u.x, v.x);
r.y0 = MIN4(s.y, t.y, u.y, v.y);
r.x1 = MAX4(s.x, t.x, u.x, v.x);
r.y1 = MAX4(s.y, t.y, u.y, v.y);
return r;
}

View file

@ -1,91 +0,0 @@
#include "fitz-base.h"
/* Make this thread local storage if you wish. */
static void *stdmalloc(fz_memorycontext *mem, int n)
{
#if 0
void *p = malloc(n);
if (!p)
fprintf(stderr, "failed to malloc %d bytes\n", n);
return p;
#else
return malloc(n);
#endif
}
static void *stdrealloc(fz_memorycontext *mem, void *p, int n)
{
#if 0
void *np = realloc(p, n);
if (np == nil)
fprintf(stderr, "realloc failed %d nytes", n);
else if (np == p)
fprintf(stderr, "realloc kept %d\n", n);
else
fprintf(stderr, "realloc moved %d\n", n);
return np;
#else
return realloc(p, n);
#endif
}
static void stdfree(fz_memorycontext *mem, void *p)
{
free(p);
}
static fz_memorycontext defmem = { stdmalloc, stdrealloc, stdfree };
static fz_memorycontext *curmem = &defmem;
fz_error fz_koutofmem = {
-1,
{"out of memory"},
{"<malloc>"},
{"memory.c"},
0
};
fz_memorycontext *
fz_currentmemorycontext()
{
return curmem;
}
void
fz_setmemorycontext(fz_memorycontext *mem)
{
curmem = mem;
}
void *
fz_malloc(int n)
{
fz_memorycontext *mem = fz_currentmemorycontext();
return mem->malloc(mem, n);
}
void *
fz_realloc(void *p, int n)
{
fz_memorycontext *mem = fz_currentmemorycontext();
return mem->realloc(mem, p, n);
}
void
fz_free(void *p)
{
fz_memorycontext *mem = fz_currentmemorycontext();
mem->free(mem, p);
}
char *
fz_strdup(char *s)
{
int len = strlen(s);
char *ns = fz_malloc(len + 1);
if (ns)
strcpy(ns, s);
return ns;
}

View file

@ -1,75 +0,0 @@
#include "fitz-base.h"
fz_rect fz_infiniterect = { 1, 1, -1, -1 };
fz_rect fz_emptyrect = { 0, 0, 0, 0 };
static fz_irect infinite = { 1, 1, -1, -1 };
static fz_irect empty = { 0, 0, 0, 0 };
fz_irect
fz_roundrect(fz_rect f)
{
fz_irect i;
i.x0 = fz_floor(f.x0);
i.y0 = fz_floor(f.y0);
i.x1 = fz_ceil(f.x1);
i.y1 = fz_ceil(f.y1);
return i;
}
fz_rect
fz_intersectrects(fz_rect a, fz_rect b)
{
fz_rect r;
if (fz_isinfiniterect(a)) return b;
if (fz_isinfiniterect(b)) return a;
r.x0 = MAX(a.x0, b.x0);
r.y0 = MAX(a.y0, b.y0);
r.x1 = MIN(a.x1, b.x1);
r.y1 = MIN(a.y1, b.y1);
return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_emptyrect : r;
}
fz_rect
fz_mergerects(fz_rect a, fz_rect b)
{
fz_rect r;
if (fz_isinfiniterect(a) || fz_isinfiniterect(b))
return fz_infiniterect;
if (fz_isemptyrect(a)) return b;
if (fz_isemptyrect(b)) return a;
r.x0 = MIN(a.x0, b.x0);
r.y0 = MIN(a.y0, b.y0);
r.x1 = MAX(a.x1, b.x1);
r.y1 = MAX(a.y1, b.y1);
return r;
}
fz_irect
fz_intersectirects(fz_irect a, fz_irect b)
{
fz_irect r;
if (fz_isinfiniterect(a)) return b;
if (fz_isinfiniterect(b)) return a;
r.x0 = MAX(a.x0, b.x0);
r.y0 = MAX(a.y0, b.y0);
r.x1 = MIN(a.x1, b.x1);
r.y1 = MIN(a.y1, b.y1);
return (r.x1 < r.x0 || r.y1 < r.y0) ? empty : r;
}
fz_irect
fz_mergeirects(fz_irect a, fz_irect b)
{
fz_irect r;
if (fz_isinfiniterect(a) || fz_isinfiniterect(b))
return infinite;
if (fz_isemptyrect(a)) return b;
if (fz_isemptyrect(b)) return a;
r.x0 = MIN(a.x0, b.x0);
r.y0 = MIN(a.y0, b.y0);
r.x1 = MAX(a.x1, b.x1);
r.y1 = MAX(a.y1, b.y1);
return r;
}

View file

@ -1,168 +0,0 @@
enum
{
UTFmax = 3, /* maximum bytes per rune */
Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
Runeself = 0x80, /* rune and UTF sequences are the same (<) */
Runeerror = 0x80 /* decoding error in UTF */
};
enum
{
Bit1 = 7,
Bitx = 6,
Bit2 = 5,
Bit3 = 4,
Bit4 = 3,
T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
Maskx = (1<<Bitx)-1, /* 0011 1111 */
Testx = Maskx ^ 0xFF, /* 1100 0000 */
Bad = Runeerror
};
int
chartorune(int *rune, char *str)
{
int c, c1, c2;
int l;
/*
* one character sequence
* 00000-0007F => T1
*/
c = *(unsigned char*)str;
if(c < Tx) {
*rune = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
c1 = *(unsigned char*)(str+1) ^ Tx;
if(c1 & Testx)
goto bad;
if(c < T3) {
if(c < T2)
goto bad;
l = ((c << Bitx) | c1) & Rune2;
if(l <= Rune1)
goto bad;
*rune = l;
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
c2 = *(unsigned char*)(str+2) ^ Tx;
if(c2 & Testx)
goto bad;
if(c < T4) {
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
if(l <= Rune2)
goto bad;
*rune = l;
return 3;
}
/*
* bad decoding
*/
bad:
*rune = Bad;
return 1;
}
int
runetochar(char *str, int *rune)
{
int c;
/*
* one character sequence
* 00000-0007F => 00-7F
*/
c = *rune;
if(c <= Rune1) {
str[0] = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
if(c <= Rune2) {
str[0] = T2 | (c >> 1*Bitx);
str[1] = Tx | (c & Maskx);
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
str[0] = T3 | (c >> 2*Bitx);
str[1] = Tx | ((c >> 1*Bitx) & Maskx);
str[2] = Tx | (c & Maskx);
return 3;
}
int
runelen(int c)
{
int rune;
char str[10];
rune = c;
return runetochar(str, &rune);
}
int
runenlen(int *r, int nrune)
{
int nb, c;
nb = 0;
while(nrune--) {
c = *r++;
if(c <= Rune1)
nb++;
else
if(c <= Rune2)
nb += 2;
else
nb += 3;
}
return nb;
}
int
fullrune(char *str, int n)
{
int c;
if(n > 0) {
c = *(unsigned char*)str;
if(c < Tx)
return 1;
if(n > 1)
if(c < T3 || n > 2)
return 1;
}
return 0;
}

View file

@ -1,116 +0,0 @@
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* get option letter from argument vector
*/
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt; /* character checked for validity */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define EMSG ""
int getopt(int nargc, char * const * nargv, const char *ostr)
{
static char *place = EMSG; /* option letter processing */
register char *oli; /* option letter list index */
char *p;
if (!*place) { /* update scanning pointer */
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return(EOF);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return(EOF);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if (optopt == (int)'-')
return(EOF);
if (!*place)
++optind;
if (opterr) {
if (!(p = strrchr(*nargv, '/')))
p = *nargv;
else
++p;
(void)fprintf(stderr, "%s: illegal option -- %c\n",
p, optopt);
}
return(BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (!(p = strrchr(*nargv, '/')))
p = *nargv;
else
++p;
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
p, optopt);
return(BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return(optopt); /* dump back option letter */
}

View file

@ -1,35 +0,0 @@
/* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
#include <string.h>
int strlcat(char *dst, const char *src, int siz)
{
register char *d = dst;
register const char *s = src;
register int n = siz;
int dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (*d != '\0' && n-- != 0)
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return dlen + strlen(s);
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return dlen + (s - src); /* count does not include NUL */
}

View file

@ -1,32 +0,0 @@
/* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
#include <string.h>
int strlcpy(char *dst, const char *src, int siz)
{
register char *d = dst;
register const char *s = src;
register int n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

View file

@ -1,11 +0,0 @@
#include <string.h>
char *strsep(char **stringp, const char *delim)
{
char *ret = *stringp;
if (ret == NULL) return NULL;
if ((*stringp = strpbrk(*stringp, delim)) != NULL)
*((*stringp)++) = '\0';
return ret;
}

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

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

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more