Merge SLNKDWF64 branch

svn path=/Slnkdwf/trunk/; revision=23911
This commit is contained in:
Jos Groot Lipman
2015-01-21 12:09:31 +00:00
parent fe4815fdf3
commit 0e37d774d2
298 changed files with 126725 additions and 11332 deletions

View File

@@ -0,0 +1,85 @@
//
// Copyright (c) 2003-2006 by Autodesk, Inc.
//
// By using this code, you are agreeing to the terms and conditions of
// the License Agreement included in the documentation for this code.
//
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED,
// AS TO THE CORRECTNESS OF THIS CODE OR ANY DERIVATIVE
// WORKS WHICH INCORPORATE IT.
//
// AUTODESK PROVIDES THE CODE ON AN "AS-IS" BASIS
// AND EXPLICITLY DISCLAIMS ANY LIABILITY, INCLUDING
// CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
// Data and Computer Software), as applicable.
//
#include "dwfcore/Core.h"
//
// Win32 only (this will compile for Win64 too)
//
#ifdef _DWFCORE_WIN32_SYSTEM
//
// Define default global allocation/deallocation operators
//
#if defined( DWFCORE_ENABLE_MEMORY_BASE ) && defined( DWFCORE_USE_DEFAULT_MEMORY_BASE_IMPL )
void* DWFCore::DWFCoreMemory::operator new( size_t s )
{
return ::operator new( s );
}
void* DWFCore::DWFCoreMemory::operator new( size_t s, void* p )
{
p = ::operator new( s );
return p;
}
void DWFCore::DWFCoreMemory::operator delete( void* p )
{
::operator delete( p );
}
void DWFCore::DWFCoreMemory::operator delete( void* p, void* )
{
::operator delete( p );
}
#endif
//
// Win9x specific support functions
//
#ifdef DWFCORE_WIN32_INCLUDE_WIN9X_CODE
_DWFCORE_API
bool
DWFCore::IsWindows9x()
{
// OSVERSIONINFO tInfo;
// tInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
//::GetVersionEx( &tInfo );
//return (tInfo.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS);
// JGL: GetVersionEx is deprecated in VC 2013
// Wij ondersteunen gewoon geen Windows 95./98
return false;
}
#endif
#endif

View File

@@ -0,0 +1,725 @@
// Copyright (c) 1996-2006 by Autodesk, Inc.
//
// By using this code, you are agreeing to the terms and conditions of
// the License Agreement included in the documentation for this code.
//
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
// Data and Computer Software), as applicable.
//
// $Header: /Components/Internal/DWF Toolkit/v7.1/develop/global/src/dwf/whiptk/ellipse.cpp 7 7/05/05 8:56p Bangiav $
#include "whiptk/pch.h"
#include "whiptk/wversion.h"
const double PI = 3.14159265358979323846;
///////////////////////////////////////////////////////////////////////////
WT_Object::WT_ID WT_Filled_Ellipse::object_id() const
{
return Filled_Ellipse_ID;
}
///////////////////////////////////////////////////////////////////////////
WT_Object::WT_ID WT_Outline_Ellipse::object_id() const
{
return Outline_Ellipse_ID;
}
///////////////////////////////////////////////////////////////////////////
#if DESIRED_CODE(WHIP_OUTPUT)
WT_Result WT_Filled_Ellipse::serialize(WT_File & file) const
{
return WT_Ellipse::serialize (file, WD_True);
}
#else
WT_Result WT_Filled_Ellipse::serialize(WT_File &) const
{
return WT_Result::Success;
}
#endif // DESIRED_CODE()
///////////////////////////////////////////////////////////////////////////
#if DESIRED_CODE(WHIP_OUTPUT)
WT_Result WT_Outline_Ellipse::serialize(WT_File & file) const
{
return WT_Ellipse::serialize (file, WD_False);
}
#else
WT_Result WT_Outline_Ellipse::serialize(WT_File &) const
{
return WT_Result::Success;
}
#endif // DESIRED_CODE()
///////////////////////////////////////////////////////////////////////////
#if DESIRED_CODE(WHIP_OUTPUT)
WT_Result WT_Ellipse::serialize(WT_File & file, WT_Boolean filled) const
{
WD_CHECK (file.dump_delayed_drawable());
// TODO: Check rendition incarnation
// Attributes that Filled_Ellipses care about:
// color, line weight, line cap, line join,
// line pattern, fill mode, visibility, URL
// layer
WT_Integer32 parts_to_sync = WT_Rendition::Color_Bit |
// WT_Rendition::Color_Map_Bit |
// WT_Rendition::Fill_Bit |
WT_Rendition::Fill_Pattern_Bit | // strange one; move below?
WT_Rendition::Merge_Control_Bit |
WT_Rendition::BlockRef_Bit |
WT_Rendition::Visibility_Bit |
// WT_Rendition::Marker_Size_Bit |
// WT_Rendition::Marker_Symbol_Bit |
WT_Rendition::URL_Bit |
WT_Rendition::Viewport_Bit |
WT_Rendition::Layer_Bit |
WT_Rendition::Object_Node_Bit;
if (filled)
{
// do not move these bits into the "if" below, as then the only
// time the pattern will sync is on a Fill state change.
parts_to_sync |= WT_Rendition::User_Fill_Pattern_Bit |
WT_Rendition::User_Hatch_Pattern_Bit |
WT_Rendition::Contrast_Color_Bit;
if (!file.rendition().fill().fill())
{
file.desired_rendition().fill() = WD_True;
parts_to_sync |= WT_Rendition::Fill_Bit;
}
}
else
{
parts_to_sync |= WT_Rendition::Line_Weight_Bit |
WT_Rendition::Pen_Pattern_Bit |
WT_Rendition::Line_Pattern_Bit |
WT_Rendition::Dash_Pattern_Bit |
WT_Rendition::Line_Style_Bit;
if (file.rendition().fill().fill())
{
file.desired_rendition().fill() = WD_False;
parts_to_sync |= WT_Rendition::Fill_Bit;
}
}
WD_CHECK (file.desired_rendition().sync(file, parts_to_sync));
if (file.heuristics().apply_transform())
((WT_Filled_Ellipse *)this)->transform(file.heuristics().transform()); // Cast "this" from const to alterable
if (file.heuristics().allow_binary_data())
{
WT_Logical_Point relpos = file.update_current_point(m_position);
// Binary output
if (m_major != m_minor)
{
// output as Ellipse
WD_CHECK (file.write ((WT_Byte)'e'));
WD_CHECK (file.write (1, &relpos));
WD_CHECK (file.write (m_major));
WD_CHECK (file.write (m_minor));
WD_CHECK (file.write (m_start));
WD_CHECK (file.write ((WT_Unsigned_Integer16)(m_end & 0xFFFF)));
return file.write (m_tilt);
}
else if (m_start != m_end)
{
// Output a 32 bit partial circle
// merge any ellipse tilt into the circle angles
long start = ((long)m_start + (long)m_tilt) & 0x0000FFFF;
long end = ((long)m_end + (long)m_tilt) & 0x0000FFFF;
WD_CHECK (file.write ((WT_Byte)0x92));
WD_CHECK (file.write (1, &relpos));
WD_CHECK (file.write (m_major));
WD_CHECK (file.write ((WT_Unsigned_Integer16)start));
return file.write ((WT_Unsigned_Integer16)end);
}
else if (WD_fits_in_short (relpos.m_x) && WD_fits_in_short (relpos.m_y) &&
WD_fits_in_short (m_major))
{
// Output a 16 bit relative full circle
WT_Logical_Point_16 tmp_point;
tmp_point = relpos;
WD_CHECK (file.write ((WT_Byte)0x12));
WD_CHECK (file.write (1, &tmp_point));
return file.write ((WT_Integer16)m_major);
}
else
{
// Output a 32 bit relative full circle
WD_CHECK (file.write ((WT_Byte)'r'));
WD_CHECK (file.write (1, &relpos));
return file.write (m_major);
}
} // allow binary data
else
{
// ASCII only output -----------------------
WD_CHECK (file.write_geom_tab_level());
if (m_major != m_minor)
{
// output as Ellipse in ASCII
if ((m_start != m_end) || m_tilt)
{
// Full description of an ellipse
WD_CHECK (file.write ("(Ellipse "));
WD_CHECK (file.write_ascii (m_position));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (m_major));
WD_CHECK (file.write ((WT_Byte) ','));
WD_CHECK (file.write_ascii (m_minor));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (m_start));
WD_CHECK (file.write ((WT_Byte) ','));
WD_CHECK (file.write_ascii (m_end));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (m_tilt));
return file.write((WT_Byte) ')');
}
else
{
// Basic description of an ellipse
WD_CHECK (file.write ("E "));
WD_CHECK (file.write_ascii (1, &m_position));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (m_major));
WD_CHECK (file.write ((WT_Byte) ','));
return file.write_ascii (m_minor);
}
}
else
{
// merge any ellipse tilt into the circle angles
long start = ((long)m_start + (long)m_tilt) & 0x0000FFFF;
long end = ((long)m_end + (long)m_tilt) & 0x0000FFFF;
// Output a circle in ASCII
if (start != end)
{
// Full description of the circle/arc
WD_CHECK (file.write ("(Circle "));
WD_CHECK (file.write_ascii (m_position));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (m_major));
WD_CHECK (file.write ((WT_Byte) ' '));
WD_CHECK (file.write_ascii (start));
WD_CHECK (file.write ((WT_Byte) ','));
WD_CHECK (file.write_ascii (end));
return file.write((WT_Byte) ')');
}
else
{
// Basic circle
WD_CHECK (file.write ("R "));
WD_CHECK (file.write_ascii (m_position));
WD_CHECK (file.write ((WT_Byte) ' '));
return file.write_ascii (m_major);
}
}
}
}
#else
WT_Result WT_Ellipse::serialize(WT_File &, WT_Boolean) const
{
return WT_Result::Success;
}
#endif // DESIRED_CODE()
///////////////////////////////////////////////////////////////////////////
bool containsAngle(double angle, double angleStart, double angleEnd)
{
// get the orientation
bool isCCW = angleStart < angleEnd;
// put the supplied parameter value on the extent side of the start angle
if (isCCW)
{
while (angle < angleStart)
angle += 2.0*PI;
while (angle- 2.0*PI > angleStart)
angle -= 2.0*PI;
}
else
{
while (angle > angleStart)
angle -= 2.0*PI;
while (angle+2.0*PI < angleStart)
angle += 2.0*PI;
}
// do the range check
if (isCCW)
{
// normal orientation
if (angle >= angleStart && angle <= angleEnd)
return true;
}
else
{
// reversed orientation
if (angle >= angleEnd && angle <= angleStart)
return true;
}
// not in range
return false;
}
///////////////////////////////////////////////////////////////////////////
void WT_Ellipse::update_bounds(WT_File * file)
{
//Bounds algorithm lifted and ported from Kona
double maj = major();
double min = minor();
double ang = tilt_radian();
double csa = cos(ang);
double sna = sin(ang);
double ax = maj * csa;
double bx = min * sna;
double ay = maj * sna;
double by = min * csa;
double xmax = sqrt(ax*ax + bx*bx);
double ymax = sqrt(ay*ay + by*by);
double asValue = start_radian();;
double css = cos(asValue);
double sns = sin(asValue);
double xs = ax*css - bx*sns;
double ys = ay*css + by*sns;
double ae = end_radian();
double cse = cos(ae);
double sne = sin(ae);
double xe = ax*cse - bx*sne;
double ye = ay*cse + by*sne;
WT_Drawable::update_bounds(WT_Logical_Point((int)xs+m_position.m_x,(int)ys+m_position.m_y), file);
WT_Drawable::update_bounds(WT_Logical_Point(((int)xs)+m_position.m_x+1,((int)ys)+m_position.m_y+1), file);
WT_Drawable::update_bounds(WT_Logical_Point((int)xe+m_position.m_x,(int)ye+m_position.m_y), file);
WT_Drawable::update_bounds(WT_Logical_Point(((int)xe)+m_position.m_x+1,((int)ye)+m_position.m_y+1), file);
double asnorm = atan2(sns, css);
double aenorm = ae + (asnorm - asValue);
double txmax = atan2(-min*sna, maj*csa);
double txmin = txmax - PI;
if (txmin <= -PI)
txmin += 2.0*PI;
if (containsAngle(txmax, asnorm, aenorm))
WT_Drawable::update_bounds(WT_Logical_Point(((int)xmax)+m_position.m_x+1, ((int)ys)+m_position.m_y+1), file);
if (containsAngle(txmin, asnorm, aenorm))
WT_Drawable::update_bounds(WT_Logical_Point((int)-xmax+m_position.m_x, (int)ys+m_position.m_y), file);
double tymax = atan2(min*csa, maj*sna);
double tymin = tymax - PI;
if (tymin <= -PI)
tymin += 2.0*PI;
if (containsAngle(tymax, asnorm, aenorm))
WT_Drawable::update_bounds(WT_Logical_Point(((int)xs)+m_position.m_x+1, ((int)ymax)+m_position.m_y+1), file);
if (containsAngle(tymin, asnorm, aenorm))
WT_Drawable::update_bounds(WT_Logical_Point((int)xs+m_position.m_x, (int)-ymax+m_position.m_y), file);
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Ellipse::materialize(WT_Opcode const & opcode, WT_File & file)
{
WT_Logical_Point tmp_point;
switch (opcode.type())
{
case WT_Opcode::Single_Byte:
{
switch (opcode.token()[0])
{
case 'E':
{
// Ellipse, single-byte full ASCII
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read_ascii (m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read_ascii (tmp_point));
m_major = tmp_point.m_x;
m_minor = tmp_point.m_y;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
} break;
case 'e':
{
// Ellipse, binary, long relative coordinates
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read (1, &m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read (m_major));
m_stage = Get_Minor;
case Get_Minor: WD_CHECK (file.read (m_minor));
m_stage = Get_Start;
case Get_Start: WD_CHECK (file.read (m_start));
m_stage = Get_End;
case Get_End: WT_Unsigned_Integer16 tmp;
WD_CHECK (file.read (tmp));
m_end = tmp;
m_stage = Get_Tilt;
case Get_Tilt: WD_CHECK (file.read (m_tilt));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// convert from relative to absolute, transform if appropriate
m_position = file.de_update_current_point(m_position);
} break;
case 'R':
{
// Basic Circle, Ascii
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read_ascii (m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read_ascii (m_major));
m_minor = m_major;
m_start = 0;
m_end = 0;
m_tilt = 0;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
} break;
case 'r':
{
// Full Circle, long relative coordinates
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read (1, &m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read (m_major));
m_minor = m_major;
m_start = 0;
m_end = 0x00010000;
m_tilt = 0;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// convert from relative to absolute, transform if appropriate
m_position = file.de_update_current_point(m_position);
} break;
case 0x12: // Ctrl-R
{
// Full Circle, short relative coordinates
WT_Logical_Point_16 position;
WT_Unsigned_Integer16 radius;
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read (1, &position));
m_position = position;
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read (radius));
m_major = m_minor = radius;
m_start = 0;
m_end = 0x00010000;
m_tilt = 0;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// convert from relative to absolute, transform if appropriate
m_position = file.de_update_current_point(m_position);
} break;
case 0x92: // X-Ctrl-R
{
// Partial or Full Circle, long relative coordinates, short angles
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read (1, &m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read (m_major));
m_minor = m_major;
m_stage = Get_Start;
case Get_Start: WD_CHECK (file.read (m_start));
m_stage = Get_End;
case Get_End: WT_Unsigned_Integer16 tmp;
WD_CHECK (file.read (tmp));
m_end = tmp;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// convert from relative to absolute, transform if appropriate
m_position = file.de_update_current_point(m_position);
} break;
default:
return WT_Result::Opcode_Not_Valid_For_This_Object;
// break;
} // switch
} break;
case WT_Opcode::Extended_ASCII:
{
if (!strcmp((char const *) opcode.token(), "(Circle"))
{
// Partial or Full Circle, absolute coordinates, short angles
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read_ascii (m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read_ascii (m_major));
m_minor = m_major;
m_stage = Get_Start;
case Get_Start: WD_CHECK (file.read_ascii (tmp_point));
if (tmp_point.m_x < 0 || tmp_point.m_y < 0)
return WT_Result::Corrupt_File_Error;
m_start = (WT_Unsigned_Integer16)(tmp_point.m_x & 0XFFFF);
m_end = tmp_point.m_y & 0x0001FFFF;
m_stage = Get_Close_Paren;
case Get_Close_Paren:
WD_CHECK (opcode.skip_past_matching_paren(file));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
}
else if (!strcmp((char const *) opcode.token(), "(Ellipse"))
{
// Ellipse, single-byte full ASCII
switch (m_stage)
{
case Get_Position: WD_CHECK (file.read_ascii (m_position));
m_stage = Get_Major;
case Get_Major: WD_CHECK (file.read_ascii (tmp_point));
m_major = tmp_point.m_x;
m_minor = tmp_point.m_y;
m_stage = Get_Start;
case Get_Start: WD_CHECK (file.read_ascii (tmp_point));
if (tmp_point.m_x < 0 || tmp_point.m_y < 0)
return WT_Result::Corrupt_File_Error;
m_start = (WT_Unsigned_Integer16)(tmp_point.m_x & 0XFFFF);
m_end = tmp_point.m_y & 0x0001FFFF;
m_stage = Get_Tilt;
case Get_Tilt: WD_CHECK (file.read_ascii (m_tilt));
m_stage = Get_Close_Paren;
case Get_Close_Paren:
WD_CHECK (opcode.skip_past_matching_paren(file));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
}
else
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
case WT_Opcode::Extended_Binary:
default:
{
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
} // switch
if (file.heuristics().apply_transform())
transform(file.heuristics().transform());
m_materialized = WD_True;
if (file.rendition().drawing_info().decimal_revision() <= WHIP20_DWF_FILE_VERSION)
{
// Note that in old versions, if m_start == m_end this is
// a null ellipse/circle that shouldn't be drawn. In this case
// we leave both m_start and m_end the same since Heidi knows not
// to draw such a case.
if (m_start == m_end)
return WT_Result::Success;
// In old versions, a complete circle was when m_end was one less than m_start.
// Adjust for the current definition which is that a complete circle is when
// they are the same value. (If you want a null circle, just don't put it
// in the DWF file, stupid!).
if (m_end < 0x00010000)
m_end++;
}
if (m_end <= m_start)
m_end += 0x00010000;
return WT_Result::Success;
}
WT_Result WT_Ellipse::skip_operand(WT_Opcode const & opcode, WT_File & file)
{
switch (opcode.type())
{
case WT_Opcode::Single_Byte:
{
switch (opcode.token()[0])
{
case 'E':
{
WT_Logical_Point tmp_pt;
WD_CHECK(file.read_ascii(tmp_pt));
WD_CHECK(file.read_ascii(tmp_pt));
} break;
case 'e':
{
// This is an ellipse, with 32-bit relative coords, 32-bit axes, 16-bit angles
file.skip(2 * sizeof(WT_Integer32) +
2 * sizeof(WT_Unsigned_Integer32) +
3 * sizeof(WT_Unsigned_Integer16));
} break;
case 'R':
{
WT_Integer32 tmp;
WT_Logical_Point tmp_pt;
WD_CHECK(file.read_ascii(tmp_pt));
WD_CHECK(file.read_ascii(tmp));
} break;
case 'r':
{
// This is a circle, with 32-bit relative coords, 32-bit radius
file.skip(2 * sizeof(WT_Integer32) +
sizeof(WT_Unsigned_Integer32));
} break;
case 0x12: // Ctrl-R
{
// This is a circle, with 16-bit relative coords, 16-bit radius
file.skip(2 * sizeof(WT_Integer16) +
sizeof(WT_Unsigned_Integer16));
} break;
case 0x92: // X-Ctrl-R
{
// This is a circle, with 32-bit relative coords, 32-bit radius, 16-bit angles
file.skip(2 * sizeof(WT_Integer32) +
sizeof(WT_Unsigned_Integer32) +
2 * sizeof(WT_Unsigned_Integer16));
} break;
default:
return WT_Result::Opcode_Not_Valid_For_This_Object;
// break;
} // switch
} break;
case WT_Opcode::Extended_ASCII:
WD_CHECK(opcode.skip_past_matching_paren(file));
break;
case WT_Opcode::Extended_Binary:
default:
{
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
} // switch
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
void WT_Ellipse::transform(WT_Transform const & transform)
{
if (!m_transformed)
{
// m_position.m_x = (WT_Integer32)((m_position.m_x + transform.m_translate.m_x) * transform.m_x_scale);
// m_position.m_y = (WT_Integer32)((m_position.m_y + transform.m_translate.m_y) * transform.m_y_scale);
// m_position.m_x = (WT_Integer32)((m_position.m_x * transform.m_x_scale) + transform.m_translate.m_x);
// m_position.m_y = (WT_Integer32)((m_position.m_y * transform.m_y_scale) + transform.m_translate.m_y);
WT_Logical_Point orig_pt(m_position);
m_position = orig_pt * transform; // we should use *=, but there seems to be a problem?
m_major = (WT_Unsigned_Integer32)(m_major * transform.m_x_scale);
m_minor = (WT_Unsigned_Integer32)(m_minor * transform.m_y_scale);
if (m_major < 0)
m_major = - m_major;
if (m_minor < 0)
m_minor = - m_minor;
m_tilt = (WT_Unsigned_Integer16)(
(WT_Unsigned_Integer16)
( (long)m_tilt +
(long)WD_90_DEGREES_AS_SHORT * ((double)transform.rotation() / 90)
) & 0x0000FFFF);
// TODO: note that we can simplify some ellipses by incorporating the tilt in and
// exchanging the major and minor axes or by rotating the start and end points.
m_transformed = WD_True;
}
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Filled_Ellipse::process(WT_File & file)
{
WD_Assert (file.filled_ellipse_action());
return (file.filled_ellipse_action())(*this, file);
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Filled_Ellipse::default_process(WT_Filled_Ellipse &, WT_File &)
{
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Outline_Ellipse::process(WT_File & file)
{
WD_Assert (file.outline_ellipse_action());
return (file.outline_ellipse_action())(*this, file);
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Outline_Ellipse::default_process(WT_Outline_Ellipse &, WT_File &)
{
return WT_Result::Success;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
// Copyright (c) 1996-2006 by Autodesk, Inc.
//
// By using this code, you are agreeing to the terms and conditions of
// the License Agreement included in the documentation for this code.
//
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
// Data and Computer Software), as applicable.
//
// $Header: /NewRoot/DWF Toolkit/v6/develop/global/src/dwf/whiptk/logical_point.cpp 1 9/12/04 8:54p Evansg $
#include "whiptk/pch.h"
///////////////////////////////////////////////////////////////////////////
WT_Boolean WT_Logical_Point::operator== (WT_Logical_Point_16 const & lp) const
{
if (m_x == (WT_Integer32)lp.m_x &&
m_y == (WT_Integer32)lp.m_y)
return WD_True;
else
return WD_False;
}
///////////////////////////////////////////////////////////////////////////
WT_Logical_Point const & WT_Logical_Point::operator= (WT_Logical_Point_16 const & in)
{
m_x = (WT_Integer32) in.m_x;
m_y = (WT_Integer32) in.m_y;
return *this;
}
///////////////////////////////////////////////////////////////////////////
const double myPI = 3.14159265358979323846;
/////////////////////////
WT_Logical_Point const WT_Logical_Point::operator* (WT_Transform const & trans) const
{
WT_Logical_Point new_point;
// new_point.m_x = (WT_Integer32) ( ((double)m_x + trans.m_translate.m_x) * trans.m_x_scale );
// new_point.m_y = (WT_Integer32) ( ((double)m_y + trans.m_translate.m_y) * trans.m_y_scale );
switch (trans.rotation())
{
case 0:
new_point.m_x = (WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x);
new_point.m_y = (WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y);
break;
case 90:
new_point.m_x = 0x7FFFFFFF - ((WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y));
new_point.m_y = (WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x);
break;
case 180:
new_point.m_x = 0x7FFFFFFF - ((WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x));
new_point.m_y = 0x7FFFFFFF - ((WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y));
break;
case 270:
new_point.m_x = (WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y);
new_point.m_y = 0x7FFFFFFF - ((WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x));
break;
default:
{
// Merk op: de code hierboven roteert om (INT_MAX/2, INT_MAX/2)
// Bij 90 graden rotaties heb je dan geen kans op overflow.
// Bij andere hoeken kan het wel mis gaan. Wij roteren hieronder
// daarom om 0,0. Dat blijkt in de praktijk goed te gaan?
double sinAngle = sin((double)trans.rotation() / 180.0 * myPI);
double cosAngle = cos((double)trans.rotation() / 180.0 * myPI);
double transx = (double)m_x * trans.m_x_scale + trans.m_translate.m_x;
double transy = (double)m_y * trans.m_y_scale + trans.m_translate.m_y;
double newx = transx * cosAngle - transy * sinAngle;
double newy = transy * cosAngle + transx * sinAngle;
// if (newx>INT_MAX || newy>INT_MAX || newx<INT_MIN || newy<INT_MIN)
// DebugBreak();
new_point.m_x = (WT_Integer32)newx;
new_point.m_y = (WT_Integer32)newy;
//throw WT_Result::Internal_Error;
}
}
return new_point;
}
///////////////////////////////////////////////////////////////////////////
WT_Logical_Point const WT_Logical_Point::operator*= (WT_Transform const & trans)
{
// Need a temp copy since with some rotations will be mucking with intermediate terms
WT_Logical_Point orig_point(m_x, m_y);
*this = orig_point * trans;
return *this;
}

860
Whiptk770/whiptk/text.cpp Normal file
View File

@@ -0,0 +1,860 @@
// Copyright (c) 1996-2006 by Autodesk, Inc.
//
// By using this code, you are agreeing to the terms and conditions of
// the License Agreement included in the documentation for this code.
//
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
// Data and Computer Software), as applicable.
//
// $Header: /Components/Internal/DWF Toolkit/v7.1/develop/global/src/dwf/whiptk/text.cpp 10 8/21/05 7:36p Gopalas $
#include "whiptk/pch.h"
#include <stddef.h>
#include <assert.h>
///////////////////////////////////////////////////////////////////////////
WT_Text::WT_Text (WT_Text const &in)
: WT_Drawable()
, m_position(in.m_position)
, m_string(in.m_string)
, m_option_bounds(in.m_option_bounds)
, m_option_overscore(in.m_option_overscore)
, m_option_underscore(in.m_option_underscore)
, m_option_reserved(in.m_option_reserved)
, m_stage(in.m_stage)
, m_transformed(in.m_transformed)
, m_relativized(in.m_relativized)
, m_optioncode(in.m_optioncode)
, m_obsolete_font_holder(in.m_obsolete_font_holder)
, m_obsolete_length_holder(in.m_obsolete_length_holder)
, m_obsolete_msg_holder(in.m_obsolete_msg_holder)
{
}
///////////////////////////////////////////////////////////////////////////
WT_Text const & WT_Text::operator= (WT_Text const & in)
{
m_position = in.m_position;
m_string = in.m_string;
m_option_bounds = in.m_option_bounds;
m_option_overscore = in.m_option_overscore;
m_option_underscore = in.m_option_underscore;
m_option_reserved = in.m_option_reserved;
m_stage = in.m_stage;
m_transformed = in.m_transformed;
m_relativized = in.m_relativized;
m_optioncode = in.m_optioncode;
m_obsolete_font_holder = in.m_obsolete_font_holder;
m_obsolete_length_holder = in.m_obsolete_length_holder;
m_obsolete_msg_holder = in.m_obsolete_msg_holder;
return *this;
}
///////////////////////////////////////////////////////////////////////////
WT_Text::WT_Text ()
: m_position (WT_Logical_Point (0,0))
, m_stage (Getting_Started)
, m_transformed (WD_False)
, m_relativized (WD_False)
, m_obsolete_font_holder (WD_Null)
{ }
///////////////////////////////////////////////////////////////////////////
WT_Text::~WT_Text()
{
if (m_obsolete_font_holder)
delete m_obsolete_font_holder;
}
///////////////////////////////////////////////////////////////////////////
WT_Text::WT_Text (WT_Logical_Point const & position,
WT_String const & string,
WT_Logical_Point const * bounds,
WT_Unsigned_Integer16 overscore_count,
WT_Unsigned_Integer16 const * overscore_pos,
WT_Unsigned_Integer16 underscore_count,
WT_Unsigned_Integer16 const * underscore_pos)
: m_position (position)
, m_string(string)
, m_stage (Getting_Started)
, m_transformed (WD_False)
, m_relativized (WD_False)
, m_obsolete_font_holder (WD_Null)
{
m_option_bounds.set(bounds);
if (overscore_count)
m_option_overscore.set(overscore_count, overscore_pos);
if (underscore_count)
m_option_underscore.set(underscore_count, underscore_pos);
}
///////////////////////////////////////////////////////////////////////////
WT_Text::WT_Text (WT_Logical_Point const & position,
WT_String const & string)
: m_position (position)
, m_string(string)
, m_stage (Getting_Started)
, m_transformed (WD_False)
, m_relativized (WD_False)
, m_obsolete_font_holder (WD_Null)
{
}
///////////////////////////////////////////////////////////////////////////
WT_Object::WT_ID WT_Text::object_id() const
{
return Text_ID;
}
///////////////////////////////////////////////////////////////////////////
#if DESIRED_CODE(WHIP_OUTPUT)
WT_Result WT_Text::serialize(WT_File & file) const
{
WD_CHECK (file.dump_delayed_drawable());
// BPM: This is a hack, but is the best I can do for now.
// Here's the issue: if Tahoe has set the heuristic to flip landscape into portrait,
// then we actually need the Font attribute to have a different rotation.
// The rotation code will do the adjustment, but we need to make sure that
// the rendition sync code "thinks" the font attribute might need updating.
file.desired_rendition().font().rotation() = file.desired_rendition().font().rotation();
WT_Integer32 parts_to_sync = WT_Rendition::Color_Bit |
// WT_Rendition::Color_Map_Bit |
// WT_Rendition::Fill_Bit |
// WT_Rendition::Fill_Pattern_Bit |
// WT_Rendition::Merge_Control_Bit |
WT_Rendition::BlockRef_Bit |
WT_Rendition::Visibility_Bit |
// WT_Rendition::Line_Weight_Bit |
WT_Rendition::Pen_Pattern_Bit |
// WT_Rendition::Line_Pattern_Bit |
// WT_Rendition::Line_Caps_Bit |
// WT_Rendition::Line_Join_Bit |
// WT_Rendition::Marker_Size_Bit |
// WT_Rendition::Marker_Symbol_Bit |
WT_Rendition::URL_Bit |
WT_Rendition::Layer_Bit |
WT_Rendition::Viewport_Bit |
WT_Rendition::Font_Extension_Bit |
WT_Rendition::Font_Bit |
WT_Rendition::Object_Node_Bit |
WT_Rendition::Text_Background_Bit |
WT_Rendition::Text_HAlign_Bit |
WT_Rendition::Text_VAlign_Bit |
WT_Rendition::Contrast_Color_Bit;
// WT_Rendition::Delineate_Bit
WD_CHECK (file.desired_rendition().sync(file, parts_to_sync));
if (file.heuristics().apply_transform())
((WT_Text *)this)->transform (file.heuristics().transform());
if (file.heuristics().allow_binary_data())
{
((WT_Text *)this)->relativize(file);
if (m_option_bounds.bounds() ||
m_option_overscore.count() ||
m_option_underscore.count())
{
// Advanced binary text
WD_CHECK (file.write((WT_Byte) 0x18)); // CTRL-X
WD_CHECK (file.write(1, &m_position));
WD_CHECK (m_string.serialize(file, WD_True));
WD_CHECK (m_option_overscore.serialize(*this, file));
WD_CHECK (m_option_underscore.serialize(*this, file));
WD_CHECK (m_option_bounds.serialize(*this, file));
if (file.heuristics().target_version() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
WD_CHECK (m_option_reserved.serialize(*this, file));
}
else
{
// Basic binary text
WD_CHECK (file.write((WT_Byte) 'x'));
WD_CHECK (file.write(1, &m_position));
WD_CHECK (m_string.serialize(file, WD_True));
}
} // if (allow binary data)
else
{
// Extended ASCII
// Don't relativize ASCII objects
WD_CHECK (file.write_geom_tab_level());
WD_CHECK (file.write("(Text "));
WD_CHECK (file.write_ascii(m_position));
WD_CHECK (file.write((WT_Byte) ' '));
WD_CHECK (m_string.serialize(file));
WD_CHECK (m_option_overscore.serialize(*this, file));
WD_CHECK (m_option_underscore.serialize(*this, file));
WD_CHECK (m_option_bounds.serialize(*this, file));
if (file.heuristics().target_version() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
WD_CHECK (m_option_reserved.serialize(*this, file));
WD_CHECK (file.write((WT_Byte) ')'));
} // else (extended ASCII output)
return WT_Result::Success;
}
#else
WT_Result WT_Text::serialize(WT_File &) const
{
return WT_Result::Success;
}
#endif // DESIRED_CODE()
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Text::materialize(WT_Opcode const & opcode, WT_File & file)
{
switch (opcode.type())
{
case WT_Opcode::Single_Byte:
{
if (file.rendition().drawing_info().decimal_revision() < REVISION_WHEN_DRAW_TEXT_ATTRIBUTES_REMOVED)
return materialize_obsolete_form(opcode, file); // Old obsolete version of DrawText opcode
else
{
// Current version of DrawText opcode
switch (opcode.token()[0])
{
case 0x18: // Ctrl-X
{
switch (m_stage)
{
case Getting_Started:
m_stage = Getting_Position;
// No break;
case Getting_Position:
WD_CHECK (file.read(1, &m_position));
m_stage = Getting_String;
// No break
case Getting_String:
WD_CHECK (m_string.materialize(file));
m_stage = Getting_Overscore;
// No break
case Getting_Overscore:
WD_CHECK (m_option_overscore.materialize(*this, m_optioncode, file));
m_stage = Getting_Underscore;
// No break
case Getting_Underscore:
WD_CHECK (m_option_underscore.materialize(*this, m_optioncode, file));
m_stage = Getting_Bounds;
// No break
case Getting_Bounds:
WD_CHECK (m_option_bounds.materialize(*this, m_optioncode, file));
m_stage = Getting_Reserved;
// No break
case Getting_Reserved:
if (file.rendition().drawing_info().decimal_revision() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
WD_CHECK (m_option_reserved.materialize(*this, m_optioncode, file));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
}
} // case Ctrl-X
break;
case 'x':
{
switch (m_stage)
{
case Getting_Started:
m_stage = Getting_Position;
// No break
case Getting_Position:
WD_CHECK (file.read(1, &m_position));
m_stage = Getting_String;
// No break
case Getting_String:
WD_CHECK (m_string.materialize(file));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
} // switch (m_stage)
} break; // case 'x'
default:
return WT_Result::Opcode_Not_Valid_For_This_Object; // Illegal opcode token
} // switch (opcode token)
} // else (current version of DrawText)
m_relativized = WD_True;
de_relativize(file);
} break;
case WT_Opcode::Extended_ASCII:
{
switch (m_stage)
{
case Getting_Started:
m_stage = Getting_Position;
// No break
case Getting_Position:
WD_CHECK (file.read_ascii(m_position));
m_stage = Getting_String;
// No break
case Getting_String:
WD_CHECK (m_string.materialize(file));
m_stage = Getting_Next_Optioncode;
// No break
Getting_Next_Optioncode_Hop:
case Getting_Next_Optioncode:
WD_CHECK(m_optioncode.get_optioncode(file));
if (m_optioncode.type() == WT_Opcode::Null_Optioncode)
{
m_stage = Skipping_Last_Paren;
goto Skipping_Last_Paren_Hop;
}
m_stage = Materializing_Option;
// No Break;
case Materializing_Option:
switch (m_optioncode.option_id())
{
case WT_Text_Optioncode::Overscore_Option:
WD_CHECK(m_option_overscore.materialize(*this, m_optioncode, file));
break;
case WT_Text_Optioncode::Underscore_Option:
WD_CHECK(m_option_underscore.materialize(*this, m_optioncode, file));
break;
case WT_Text_Optioncode::Bounds_Option:
WD_CHECK(m_option_bounds.materialize(*this, m_optioncode, file));
break;
case WT_Text_Optioncode::Reserved_Option:
WD_CHECK(m_option_reserved.materialize(*this, m_optioncode, file));
break;
case WT_Text_Optioncode::Unknown_Option:
WD_CHECK(m_optioncode.skip_past_matching_paren(file));
break;
default:
return WT_Result::Internal_Error;
} // switch (m_sub_option.option_id())
m_stage = Getting_Next_Optioncode;
goto Getting_Next_Optioncode_Hop;
Skipping_Last_Paren_Hop:
case Skipping_Last_Paren:
WD_CHECK (opcode.skip_past_matching_paren(file));
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
} // switch (m_stage)
} break; // ASCII
case WT_Opcode::Extended_Binary:
default:
{
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
} // switch
if (file.heuristics().apply_transform())
transform(file.heuristics().transform());
m_materialized = WD_True;
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Text::materialize_obsolete_form(WT_Opcode const & opcode, WT_File & file)
{
WT_Integer16 tmp_int16;
WT_Integer32 tmp_int32;
switch (opcode.token()[0])
{
case 'x':
{
switch (m_stage)
{
case Getting_Started:
WD_Assert(!m_obsolete_font_holder);
m_obsolete_font_holder = new WT_Font;
if (!m_obsolete_font_holder)
return WT_Result::Out_Of_Memory_Error;
m_obsolete_font_holder->set_fields_defined( WT_Font::FONT_HEIGHT_BIT |
WT_Font::FONT_ROTATION_BIT |
WT_Font::FONT_OBLIQUE_BIT |
WT_Font::FONT_WIDTH_SCALE_BIT |
WT_Font::FONT_SPACING_BIT |
WT_Font::FONT_FLAGS_BIT );
m_stage = Getting_Width_Scale;
// No break
case Getting_Width_Scale:
WD_CHECK (file.read(tmp_int16));
m_obsolete_font_holder->width_scale().set(tmp_int16);
m_stage = Getting_Spacing;
case Getting_Spacing:
WD_CHECK (file.read(tmp_int16));
m_obsolete_font_holder->spacing().set(tmp_int16);
m_stage = Getting_Flags;
case Getting_Flags:
WD_CHECK (file.read(tmp_int32));
m_obsolete_font_holder->flags().set(tmp_int32);
m_stage = Getting_Oblique_Angle;
// No break
case Getting_Oblique_Angle:
WD_CHECK (file.read(tmp_int16));
m_obsolete_font_holder->oblique().set(tmp_int16);
m_stage = Getting_Overscore;
// No break
case Getting_Overscore:
WD_CHECK (m_option_overscore.materialize(*this, m_optioncode, file));
m_stage = Getting_Underscore;
// No break
case Getting_Underscore:
WD_CHECK (m_option_underscore.materialize(*this, m_optioncode, file));
m_stage = Getting_Rotation;
// No break
case Getting_Rotation:
WD_CHECK (file.read(tmp_int16));
m_obsolete_font_holder->rotation().set(tmp_int16);
m_stage = Getting_Height;
// No break
case Getting_Height:
WD_CHECK (file.read(tmp_int32));
if (file.heuristics().apply_transform())
tmp_int32 = (WT_Integer32) (tmp_int32 * file.heuristics().transform().m_y_scale);
m_obsolete_font_holder->height().set(tmp_int32);
m_stage = Getting_Position;
// No break
case Getting_Position:
WD_CHECK (file.read(1, &m_position));
m_stage = Getting_BBox_Deltas;
// No break
case Getting_BBox_Deltas:
{
WT_Logical_Point tmp_bbox[4];
WD_CHECK (file.read(4, tmp_bbox));
// convert from relative to absolute
m_position = file.de_update_current_point(m_position);
m_relativized = WD_False;
WT_Integer32 delta[8];
delta[0] = tmp_bbox[0].m_x;
delta[1] = tmp_bbox[0].m_y;
delta[2] = tmp_bbox[1].m_x;
delta[3] = tmp_bbox[1].m_y;
delta[4] = tmp_bbox[2].m_x;
delta[5] = tmp_bbox[2].m_y;
delta[6] = tmp_bbox[3].m_x;
delta[7] = tmp_bbox[3].m_y;
tmp_bbox[0].m_x = m_position.m_x + delta[4];
tmp_bbox[0].m_y = m_position.m_y + delta[6];
tmp_bbox[1].m_x = tmp_bbox[0].m_x + delta[7];
tmp_bbox[1].m_y = tmp_bbox[0].m_y + delta[5];
tmp_bbox[2].m_x = tmp_bbox[1].m_x + delta[2];
tmp_bbox[2].m_y = tmp_bbox[1].m_y + delta[3];
tmp_bbox[3].m_x = tmp_bbox[0].m_x + delta[0];
tmp_bbox[3].m_y = tmp_bbox[0].m_y + delta[1];
m_option_bounds.set(tmp_bbox);
m_stage = Getting_Str_Length;
}
// No break
case Getting_Str_Length:
WD_CHECK (file.read_count(m_obsolete_length_holder));
m_obsolete_msg_holder = new unsigned short[m_obsolete_length_holder + 1];
if (!m_obsolete_msg_holder)
return WT_Result::Out_Of_Memory_Error;
m_stage = Getting_Msg;
// No break
case Getting_Msg:
WD_CHECK (file.read( 2 * m_obsolete_length_holder, (WT_Byte *)m_obsolete_msg_holder));
m_obsolete_msg_holder[m_obsolete_length_holder] = 0;
m_string.set(m_obsolete_length_holder, m_obsolete_msg_holder);
delete []m_obsolete_msg_holder;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
} // switch (m_stage)
if (file.heuristics().apply_transform())
transform(file.heuristics().transform());
} break;
case 0x18:
{
WT_Integer32 tmp_int32;
WT_Integer16 tmp_int16;
switch (m_stage)
{
case Getting_Started:
WD_Assert(!m_obsolete_font_holder);
m_obsolete_font_holder = new WT_Font;
if (!m_obsolete_font_holder)
return WT_Result::Out_Of_Memory_Error;
m_obsolete_font_holder->set_fields_defined( WT_Font::FONT_HEIGHT_BIT |
WT_Font::FONT_ROTATION_BIT );
m_stage = Getting_Rotation;
case Getting_Rotation:
WD_CHECK (file.read(tmp_int16));
m_obsolete_font_holder->rotation().set(tmp_int16);
m_stage = Getting_Height;
case Getting_Height:
WD_CHECK (file.read(tmp_int32));
if (file.heuristics().apply_transform())
tmp_int32 = (WT_Integer32) (tmp_int32 * file.heuristics().transform().m_y_scale);
m_obsolete_font_holder->height().set(tmp_int32);
m_stage = Getting_Position;
case Getting_Position:
WD_CHECK (file.read(1, &m_position));
m_relativized = WD_True;
m_stage = Getting_Str_Length;
case Getting_Str_Length:
WD_CHECK (file.read_count(m_obsolete_length_holder));
m_obsolete_msg_holder = new unsigned short[m_obsolete_length_holder + 1];
if (!m_obsolete_msg_holder)
return WT_Result::Out_Of_Memory_Error;
m_stage = Getting_Msg;
// No break
case Getting_Msg:
WD_CHECK (file.read( 2 * m_obsolete_length_holder, (WT_Byte *)m_obsolete_msg_holder));
m_obsolete_msg_holder[m_obsolete_length_holder] = 0;
m_string.set(m_obsolete_length_holder, m_obsolete_msg_holder);
delete []m_obsolete_msg_holder;
m_stage = Completed;
break;
default:
return WT_Result::Internal_Error;
} // switch (m_stage)
} break;
default:
{
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
} // switch
de_relativize(file);
if (file.heuristics().apply_transform())
transform(file.heuristics().transform());
m_materialized = WD_True;
// Now send these WT_Font attributes off for processing...
if (m_obsolete_font_holder)
{
m_obsolete_font_holder->process(file);
delete m_obsolete_font_holder;
m_obsolete_font_holder = WD_Null;
}
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Text::skip_operand(WT_Opcode const & opcode, WT_File & file)
{
switch (opcode.type())
{
case WT_Opcode::Single_Byte:
{
return materialize(opcode, file);
} break;
case WT_Opcode::Extended_ASCII:
WD_CHECK (opcode.skip_past_matching_paren(file));
break;
case WT_Opcode::Extended_Binary:
default:
{
return WT_Result::Opcode_Not_Valid_For_This_Object;
} break;
} // switch
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
void WT_Text::transform(WT_Transform const & transform)
{
if (!m_transformed)
{
WT_Logical_Point tmp_pt;
tmp_pt = m_position;
m_position = tmp_pt * transform;
m_option_bounds.transform(transform);
m_transformed = WD_True;
}
}
///////////////////////////////////////////////////////////////////////////
WT_Result WT_Text::process(WT_File & file)
{
WD_Assert (file.text_action());
return (file.text_action())(*this, file);
}
WT_Result WT_Text::default_process(WT_Text &, WT_File &)
{
return WT_Result::Success;
}
///////////////////////////////////////////////////////////////////////////
#if DESIRED_CODE(WHIP_OUTPUT)
void WT_Text::relativize(WT_File & file)
{
if (!m_relativized)
{
m_position = file.update_current_point(m_position);
m_option_bounds.relativize(file);
m_relativized = WD_True;
} // If (!relativized)
}
#else
void WT_Text::relativize(WT_File &)
{
}
#endif // DESIRED_CODE()
///////////////////////////////////////////////////////////////////////////
void WT_Text::de_relativize(WT_File & file)
{
if (m_relativized)
{
m_position = file.de_update_current_point(m_position);
m_option_bounds.de_relativize(file);
m_relativized = WD_False;
} // If (!relativized)
}
///////////////////////////////////////////////////////////////////////////
// FIXME: WT_Text::update_bounds is completely Win32 specific, and must be ported.
#ifdef WD_WIN32_SYSTEM
#include <tchar.h>
#pragma comment (lib, "gdi32.lib") //for font bounds approximation
void WT_Text::update_bounds(WT_File * file)
{
if (m_option_bounds.bounds() != WD_Null)
{
WT_Drawable::update_bounds(m_option_bounds.bounds(), 2);
return;
}
WT_Drawable::update_bounds(m_position); //base point
if (m_string.length()==0)
return;
WT_Integer32 height = file->rendition().font().height();
int rotation = (int)((float)TWO_PI * (float)file->rendition().font().rotation() / 65536.0f);
int oblique = (int)((float)TWO_PI * (float)file->rendition().font().oblique() / 65536.0f);
BYTE charset = file->rendition().font().charset().charset();
BYTE pitch_and_family = file->rendition().font().pitch().pitch() | file->rendition().font().family().family();
UINT string_length = m_string.length();
BYTE italic = file->rendition().font().style().italic();
BYTE underline = file->rendition().font().style().underlined();
BYTE bold = file->rendition().font().style().bold();
//
// this is dangerous since it assumes wchar_t is always 16-bit uchar
//
wchar_t* facename = new wchar_t[file->rendition().font().font_name().name().length()+1];
const wchar_t* cwstr = (const wchar_t*)file->rendition().font().font_name().name().unicode();
if (cwstr)
{
wcscpy(facename, cwstr);
}
else
{
facename[0] = 0;
}
wchar_t* wstr = new wchar_t[m_string.length()+1];
wcscpy(wstr, (const wchar_t*)m_string.unicode());
HWND hwnd = NULL;
HDC hdc = NULL;
do
{
hwnd = ::GetDesktopWindow();
if (!hwnd || hwnd == INVALID_HANDLE_VALUE)
break;
hdc = ::GetDC(hwnd);
if (!hdc || hdc == INVALID_HANDLE_VALUE)
break;
LOGFONTW logfont;
logfont.lfHeight = 2048; //we'll get the right value down below
logfont.lfWidth = 0; //force aspect ratio of font
logfont.lfEscapement = oblique;
logfont.lfOrientation = rotation;
logfont.lfWeight = bold ? FW_BOLD : FW_DONTCARE;
logfont.lfItalic = italic;
logfont.lfUnderline = underline;
//logfont.lfStrikeOut;
logfont.lfCharSet = charset;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfQuality = DEFAULT_QUALITY;
logfont.lfPitchAndFamily = pitch_and_family;
memset(logfont.lfFaceName,0,LF_FACESIZE*sizeof(wchar_t));
wcsncpy(logfont.lfFaceName,facename,LF_FACESIZE);
HFONT hfont = ::CreateFontIndirectW(&logfont);
if (!hfont || hfont == INVALID_HANDLE_VALUE)
break;
//we want to get the width based on font design units, probably 2048, maybe 1024
//query and figure that out. use that as the height
HGDIOBJ hobj = ::SelectObject(hdc, hfont);
int size = ::GetOutlineTextMetricsW(hdc, 0, NULL);
if (size != 0)
{
OUTLINETEXTMETRICW *otm = (OUTLINETEXTMETRICW *)new char [size];
WD_Assert(otm != NULL);
UINT status = GetOutlineTextMetricsW (hdc, size, otm);
WD_Assert(status != 0);
if (status != 0)
logfont.lfHeight = otm->otmEMSquare;
delete [] otm;
}
else
{
logfont.lfHeight = 1000;
}
logfont.lfHeight *= -1; // Negative is more accurate
::SelectObject(hdc, hobj);
::DeleteObject(hfont);
hfont = ::CreateFontIndirectW(&logfont);
if (!hfont || hfont == INVALID_HANDLE_VALUE)
break;
hobj = ::SelectObject(hdc, hfont);
SIZE fontsize;
::GetTextExtentPointW(hdc, wstr, string_length, &fontsize);
::SelectObject(hdc, hobj);
::DeleteObject(hfont);
//now we have the width in font design units. Now translate this based on font height.
int deltaX = -(int)((double)height * (double)fontsize.cx / (double)logfont.lfHeight);
int deltaY = -(int)((double)height * (double)fontsize.cy / (double)logfont.lfHeight);
bool overflowX = (double)((m_position.m_x + deltaX) - (double)m_position.m_x) != deltaX;
bool overflowY = (double)((m_position.m_y + deltaY) - (double)m_position.m_y) != deltaY;
int ptx = overflowX //exceeded intmax?
? 0x7FFFFFFF
: m_position.m_x + deltaX;
int pty = overflowY //exceeded intmax?
? 0x7FFFFFFF
: m_position.m_y + deltaY;
// GetTextExtentPointW ignores rotation. So rotate around our basepoint ourselves
double drotation = ((float)TWO_PI * (float)file->rendition().font().rotation() / 65536.0f);
#define ROT(x,y) WT_Logical_Point(m_position.m_x+(long)((x)*cos((double)drotation)-(y)*sin((double)drotation)),\
m_position.m_y+(long)((y)*cos((double)drotation)+(x)*sin((double)drotation)))
ptx,pty;
WT_Logical_Point xx[] = { ROT(0,0),
ROT(deltaX,0),
ROT(deltaX,deltaY) ,
ROT(0,deltaY)};
// if (xx[0].m_x < 0 ||xx[1].m_x < 0 ||xx[2].m_x < 0 ||xx[3].m_x < 0)
// DebugBreak();
m_option_bounds.set(xx);
//m_option_bounds.transform(WT_Transform(m_position,1,1, 0));
WT_Drawable::update_bounds(m_option_bounds.bounds(), 4);
} while (false);
if (hdc && hdc != INVALID_HANDLE_VALUE && hwnd && hwnd != INVALID_HANDLE_VALUE)
::ReleaseDC(hwnd, hdc);
delete [] facename;
delete [] wstr;
}
#else // WD_WIN32_SYSTEM
void WT_Text::update_bounds(WT_File *) {
WD_Complain ("WT_Text::update_bounds is not implemented on this system");
}
#endif // WD_WIN32_SYSTEM

View File

@@ -0,0 +1,88 @@
//
// Copyright (c) 1996-2006 by Autodesk, Inc.
//
// By using this code, you are agreeing to the terms and conditions of
// the License Agreement included in the documentation for this code.
//
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
// Data and Computer Software), as applicable.
//
#if !defined TRANSFORM_HEADER
#define TRANSFORM_HEADER
///
///\file dwf/whiptk/transform.h
///
/// A simple transform providing translation, scaling, and simple 90, 180, 270 degree rotations.
/** \exception WT_Result::Toolkit_Usage_Error The rotation was not one of 0, 90, 180, 270.
*/
class WHIPTK_API WT_Transform
{
public:
WT_Logical_Point m_translate; /**< \brief Translation vector. */
double m_x_scale; /**< \brief X scale factor. */
double m_y_scale; /**< \brief Y scale factor. */
long m_rotation; /**< \brief Rotation (in degrees, one of 0, 90, 180, 270). */
/// Constructs a WT_Transform object.
WT_Transform()
: m_translate(0,0)
, m_x_scale(1.0)
, m_y_scale(1.0)
, m_rotation(0)
{ }
/// Constructs a WT_Transform object with the given data.
WT_Transform (
WT_Logical_Point trans, /**< Translation vector. */
double xval, /**< X scale factor. */
double yval, /**< Y scale factor. */
double rotation = 0.0 /**< Optional rotation (in degrees, one of 0, 90, 180, 270). */
)
: m_translate(trans)
, m_x_scale(xval)
, m_y_scale(yval)
{
set_rotation(rotation);
}
virtual ~WT_Transform()
{}
/// Sets the rotation value.
/** \exception WT_Result::Toolkit_Usage_Error The rotation was not one of 0, 90, 180, 270.
*/
void set_rotation(
double rotation /**< Rotation (in degrees, one of 0, 90, 180, 270). */
)
{
switch ((long)rotation)
{
case 0:
case 90:
case 180:
case 270:
m_rotation = (long)rotation;
break;
default:
m_rotation = (long)rotation;
//throw WT_Result::Toolkit_Usage_Error;
}
}
/// Returns the rotation value (in degrees, one of 0, 90, 180, 270).
long rotation() const
{ return m_rotation; }
};
#endif // TRANSFORM_HEADER