Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank-Friemel committed Dec 30, 2016
1 parent 9428c7c commit 76ba02e
Show file tree
Hide file tree
Showing 196 changed files with 66,709 additions and 1 deletion.
173 changes: 173 additions & 0 deletions 3DGlyph.cpp
@@ -0,0 +1,173 @@
#include "stdafx.h"
#include "3DGlyph.h"
#include "3DProjector.h"

#ifndef GGO_UNHINTED
#define GGO_UNHINTED 0x0100
#endif

static inline double fx_to_dbl(const FIXED& p)
{
return double(p.value) + double(p.fract) * (1.0 / 65536.0);
}


C3DGlyph::C3DGlyph()
{
}


C3DGlyph::~C3DGlyph()
{
}

void C3DGlyph::Clear()
{
__super::Clear();
m_vecFaces.clear();
}

glm::dvec3 C3DGlyph::GetBoundingBox() const
{
ATLASSERT(!m_vecVertices.empty());
return m_vecVertices[1] - m_vecVertices[0];
}

void C3DGlyph::Draw(C3DProjector* pProjector)
{
ATLASSERT(pProjector);

vector<PIXEL2D> vecPoints(m_vecVertices.size());

size_t i = 0;

bool bIsVisible = false;

for each(auto& v in m_vecVertices)
{
pProjector->VertexToPixel(v, vecPoints[i]);

if (!bIsVisible && pProjector->IsVisible(vecPoints[i]))
bIsVisible = true;
++i;
}
if (bIsVisible)
{
size_t n = m_vecFaces.size();

vector<PIXEL2D> vecPolyPoints(n);
vector<BYTE> vecPolyTypes(n);

i = 0;

for each(auto&f in m_vecFaces)
{
vecPolyPoints[i] = vecPoints[f.first];
vecPolyTypes[i++] = f.second;
}
pProjector->PolyDraw(&vecPolyPoints.front(), &vecPolyTypes.front(), n, m_colR, m_colG, m_colB, m_alpha);
}
}

bool C3DGlyph::Create(WCHAR c, const LOGFONT* pLogFont, bool bHinted /*= false*/)
{
Clear();

CClientDC hdc(NULL);

ATLASSERT(pLogFont);

// create font and select it
CFont newFont;

if (!newFont.CreateFontIndirect(pLogFont))
return false;

double lfScale = 25.0;

bool bResult = false;
auto pOldFont = hdc.SelectFont(newFont);

GLYPHMETRICS gm = { 0 };

MAT2 mat2 = { 0 };

mat2.eM11.value = 1;
mat2.eM22.value = 1;

ULONG buf_size = 16384 - 32;
CTempBuffer<BYTE> gbuf(buf_size);

int total_size = ::GetGlyphOutlineW(hdc, c, GGO_NATIVE | (bHinted ? 0 : GGO_UNHINTED), &gm, buf_size, gbuf, &mat2);

if (total_size > 0)
{
bResult = true;

// store bounding box (lower-left, upper-right)
m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1));
m_vecVertices.push_back(glm::dvec4((double)((gm.gmBlackBoxX > (UINT)gm.gmCellIncX) ? gm.gmBlackBoxX : (UINT)gm.gmCellIncX) / lfScale, ((double)gm.gmBlackBoxY) / lfScale * (-1.0), 0, 1));

const BYTE* cur_glyph = gbuf;
const BYTE* end_glyph = gbuf + total_size;

while (cur_glyph < end_glyph)
{
const TTPOLYGONHEADER* th = (const TTPOLYGONHEADER*)cur_glyph;

const BYTE* end_poly = cur_glyph + th->cb;
const BYTE* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);

m_vecVertices.push_back(glm::dvec4(fx_to_dbl(th->pfxStart.x) / lfScale, -fx_to_dbl(th->pfxStart.y) / lfScale, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size()-1, PT_MOVETO));

while (cur_poly < end_poly)
{
const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;

if (pc->wType == TT_PRIM_LINE)
{
for (int i = 0; i < pc->cpfx; i++)
{
m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pc->apfx[i].x) / lfScale, -fx_to_dbl(pc->apfx[i].y) / lfScale, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_LINETO));
}
}
else if (pc->wType == TT_PRIM_QSPLINE)
{
for (int u = 0; u < pc->cpfx - 1; u++)
{
// B is always the current point
POINTFX pnt_b = pc->apfx[u];
POINTFX pnt_c = pc->apfx[u + 1];

// if not on last spline, compute C
if (u < pc->cpfx - 2)
{
// midpoint (x,y)
*(int*)&pnt_c.x = (*(int*)&pnt_b.x + *(int*)&pnt_c.x) / 2;
*(int*)&pnt_c.y = (*(int*)&pnt_b.y + *(int*)&pnt_c.y) / 2;
}

m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pnt_b.x) / lfScale, -fx_to_dbl(pnt_b.y) / lfScale, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_BEZIERTO));

m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pnt_c.x) / lfScale, -fx_to_dbl(pnt_c.y) / lfScale, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_BEZIERTO));
}
}
cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
}
cur_glyph += th->cb;

m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_CCW_EX));
}
m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1));
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_STOP));
}
// put back the old font
hdc.SelectFont(pOldFont);

return bResult;
}
21 changes: 21 additions & 0 deletions 3DGlyph.h
@@ -0,0 +1,21 @@
#pragma once

#include "3DObject.h"

class C3DGlyph : public C3DObject
{
public:
C3DGlyph();
~C3DGlyph();

bool Create(WCHAR c, const LOGFONT* pLogFont, bool bHinted = false);

virtual void Clear();
virtual void Draw(C3DProjector* pProjector);

glm::dvec3 GetBoundingBox() const;

private:
vector<face_t> m_vecFaces;
};

89 changes: 89 additions & 0 deletions 3DObject.cpp
@@ -0,0 +1,89 @@
#include "stdafx.h"
#include "3DObject.h"
#include "3DProjector.h"

C3DObject::C3DObject()
{
m_colR = 0.0;
m_colG = 1.0;
m_colB = 0.0;
m_alpha = 1.0;
}


C3DObject::~C3DObject()
{
}

void C3DObject::Clear()
{
m_vecVertices.clear();
}

bool C3DObject::IsVisible(C3DProjector* pProjector)
{
ATLASSERT(pProjector);

vector<PIXEL2D> vecPoints(m_vecVertices.size());

size_t i = 0;

bool bIsVisible = false;

for each(auto& v in m_vecVertices)
{
pProjector->VertexToPixel(v, vecPoints[i]);

if (!bIsVisible && pProjector->IsVisible(vecPoints[i]))
{
bIsVisible = true;
break;
}
++i;
}
return bIsVisible;
}

void C3DObject::RotateX(double lfDegree)
{
glm::dvec3 myRotationAxis(1, 0, 0);

glm::dmat4 c = glm::rotate((glm::dvec3::value_type)glm::radians(lfDegree), myRotationAxis);

for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v)
*v = c * (*v);
}

void C3DObject::MoveX(double lfTrans)
{
glm::dvec3 vecTrans(lfTrans, 0, 0);
Move(vecTrans);
}

void C3DObject::MoveZ(double lfTrans)
{
glm::dvec3 vecTrans(0, 0, lfTrans);
Move(vecTrans);
}

void C3DObject::Move(const glm::dvec3& vecTrans)
{
glm::dmat4 c = glm::translate(vecTrans);

for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v)
*v = c * (*v);
}

void C3DObject::Move(const glm::dmat4& matTrans)
{
for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v)
*v = matTrans * (*v);
}

void C3DObject::Scale(double lfFactor)
{
glm::mat4 matScaling = glm::scale(glm::dvec3(lfFactor, lfFactor, lfFactor));

for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v)
*v = matScaling * (*v);
}
61 changes: 61 additions & 0 deletions 3DObject.h
@@ -0,0 +1,61 @@
///////////////////////////////////////////////////////////////////////
// 3DObject.h

#pragma once

#define PT_CCW_EX 0x08
#define PT_STOP 0x10

typedef pair<size_t, BYTE> face_t;

class C3DProjector;

class C3DObject
{
public:
C3DObject();
virtual ~C3DObject();

virtual void Clear();
virtual void Draw(C3DProjector* pProjector) = 0;
virtual bool IsVisible(C3DProjector* pProjector);

void RotateX(double lfDegree);

void Move(const glm::dmat4& matTrans);
void Move(const glm::dvec3& vecTrans);
void MoveX(double lfTrans);
void MoveZ(double lfTrans);

void Scale(double lfFactor);

inline void SetColor(double r, double g, double b)
{
m_colR = r;
m_colG = g;
m_colB = b;
}
inline glm::dvec3 GetBoundingBox() const
{
glm::dvec3 r(1);
return r;

}
inline void SetAlpha(double value)
{
if (value >= 0.0 && value <= 1.0)
m_alpha = value;
}
inline double GetAlpha() const
{
return m_alpha;
}
public:
vector<glm::dvec4> m_vecVertices;
double m_colR;
double m_colG;
double m_colB;
protected:
double m_alpha;
};

0 comments on commit 76ba02e

Please sign in to comment.