/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#ifndef _DRAWING_H_
#define _DRAWING_H_

/* NAME
 *
 * NOTES
 *
 * HISTORY
 *   frog - Jan 11, 1999: Created.
 *   frog - Nov 20, 2000: remove display function, only needed loading object from binary
 */
#include "precompile.h"

#include <math.h>

#include <comphelper/newarray.hxx>

#include "hwplib.h"
#include "hwpfile.h"
#include "hiodev.h"
#include "hbox.h"
#include "drawdef.h"

enum
{
    OBJFUNC_LOAD,
    OBJFUNC_FREE,
    OBJFUNC_DISPLAY,
    OBJFUNC_NITEM
};

enum
{
    BEGIN_GRADATION = 0, LINEAR, RADIAL, CONICAL, SQUARE,
    END_GRADATION, BITMAP_PATTERN
};

#define OBJRET_FILE_OK           0
#define OBJRET_FILE_ERROR       (-1)
#define OBJRET_FILE_NO_PRIVATE_BLOCK    (-2)
#define OBJRET_FILE_NO_PRIVATE_BLOCK_2  (-3)

typedef int (*HWPDOFuncType) (int, HWPDrawingObject *, int, void *, int);

#define HWPDOFunc(hdo, cmd, argp, argv) \
    (HWPDOFuncTbl[(hdo)->type]((hdo)->type, (hdo), (cmd), (argp), (argv)))
#define HWPDOFunc2(type, cmd, argp, argv) \
    (HWPDOFuncTbl[(type)]((type), NULL, (cmd), (argp), (argv)))

static int HWPDOLineFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDORectFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDOEllipseFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDOArcFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDOFreeFormFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDOTextBoxFunc(int, HWPDrawingObject *, int, void *, int);
static int HWPDOEllipse2Func(int, HWPDrawingObject *, int, void *, int);
static int HWPDOArc2Func(int, HWPDrawingObject *, int, void *, int);
static int HWPDOContainerFunc(int, HWPDrawingObject *, int, void *, int);
static HWPPara *LoadParaList();

HWPDOFuncType HWPDOFuncTbl[] =
{
    HWPDOContainerFunc,
    HWPDOLineFunc,
    HWPDORectFunc,
    HWPDOEllipseFunc,
    HWPDOArcFunc,
    HWPDOFreeFormFunc,
    HWPDOTextBoxFunc,
    HWPDOFreeFormFunc,
    HWPDOEllipse2Func,
    HWPDOArc2Func,
    HWPDOFreeFormFunc,
};

static HMemIODev *hmem = 0;

static int count = 0;

inline bool HAVE_FCOLOR(HWPDrawingObject * hdo)
{
    return hdo->property.fill_color != HWPDO_COLOR_NONE;
}


inline bool HAVE_PATTERN(HWPDrawingObject * hdo)
{
    return (hdo->property.pattern_type & HWPDO_PAT_TYPE_BITS)
        != HWPDO_PAT_SOLID && hdo->property.pattern_color != HWPDO_COLOR_NONE;
}


inline bool HAVE_GRADATION(HWPDrawingObject * hdo)
{
    return hdo->property.gstyle > BEGIN_GRADATION &&
        hdo->property.gstyle < END_GRADATION &&
        hdo->property.fromcolor != HWPDO_COLOR_NONE &&
        hdo->property.tocolor != HWPDO_COLOR_NONE;
}


inline bool HAVE_BITMAP_PATTERN(HWPDrawingObject * hdo)
{
    return hdo->property.gstyle == BITMAP_PATTERN &&
        hdo->property.szPatternFile[0];
}


inline bool HAS_PAT(HWPDrawingObject * hdo)
{
    return HAVE_FCOLOR(hdo) || HAVE_PATTERN(hdo) ||
        HAVE_GRADATION(hdo) || HAVE_BITMAP_PATTERN(hdo);
}


static void SetHdoParallRgn(HWPDrawingObject * hdo, int width, int height)
{
    hdo->property.parall.pt[0].x = 0;
    hdo->property.parall.pt[0].y = 0;
    hdo->property.parall.pt[1].x = width;
    hdo->property.parall.pt[1].y = 0;
    hdo->property.parall.pt[2].x = width;
    hdo->property.parall.pt[2].y = height;
}


static bool SkipPrivateBlock(int type)
{
    int n;

    if (type == OBJRET_FILE_NO_PRIVATE_BLOCK)
    {
        n = hmem->read4b();
        if (hmem->state() || hmem->skipBlock(n) != n)
            return false;
    }
    n = hmem->read4b();
    if (hmem->state())
        return false;
    return hmem->skipBlock(n) == n;
}


static int SizeExpected;
static int SizeRead;

static int ReadSizeField(int size)
{
    SizeExpected = size;
    SizeRead = hmem->read4b();
    if (hmem->state())
        return -1;
    return SizeRead;
}


static bool SkipUnusedField(void)
{
    return (SizeExpected < SizeRead) ?
        hmem->skipBlock(SizeRead - SizeExpected) != 0 : true;
}


#define HDOFILE_HEADER_SIZE (2*4+16)              // 16=sizeof(ZZRect)
#define HDOFILE_COMMON_SIZE (7*4+16+44)

#define HDOFILE_HAS_NEXT    0x01
#define HDOFILE_HAS_CHILD   0x02

/**
 * 공통 헤더를 읽어드린다.
 * 개체종류/연결정보/상대위치/개체크기/절대위치/차지영역/기본속성/회전속성/그라데이션/비트맵패턴
 */
static bool LoadCommonHeader(HWPDrawingObject * hdo, WORD * link_info)
{
    uint size, property_size, common_size;

	 if( !hmem )
		 return FALSE;
    size = hmem->read4b();
    if (hmem->state())
    {
        return FALSE;
    }
    if (size < HDOFILE_COMMON_SIZE)
    {
        return FALSE;
    }

    common_size = HDOFILE_COMMON_SIZE;
    property_size = 44;
    hdo->type = hmem->read2b();
    *link_info = sal::static_int_cast<WORD>(hmem->read2b());
    hdo->offset.x = hmem->read4b();
    hdo->offset.y = hmem->read4b();
    hdo->extent.w = hmem->read4b();
    hdo->extent.h = hmem->read4b();
    hdo->offset2.x = hmem->read4b();
    hdo->offset2.y = hmem->read4b();

    if (hmem->state())
        return FALSE;

    hdo->vrect.x = hmem->read4b();
    hdo->vrect.y = hmem->read4b();
    hdo->vrect.w = hmem->read4b();
    hdo->vrect.h = hmem->read4b();

// read bare property 44 bytes
    hdo->property.line_pstyle = hmem->read4b();
    hdo->property.line_hstyle = hmem->read4b();
    hdo->property.line_tstyle = hmem->read4b();
    hdo->property.line_color = hmem->read4b();
    hdo->property.line_width = (hunit) hmem->read4b();
    hdo->property.fill_color = hmem->read4b();
    hdo->property.pattern_type = hmem->read4b();
    hdo->property.pattern_color = hmem->read4b();
    hdo->property.hmargin = (hunit) hmem->read4b();
    hdo->property.vmargin = (hunit) hmem->read4b();
    hdo->property.flag = hmem->read4b();
// read ratation property 32 bytes
    if ((size >= common_size + 32)
        && (hdo->property.flag & HWPDO_FLAG_ROTATION))
    {
        hdo->property.rot_originx = hmem->read4b();
        hdo->property.rot_originy = hmem->read4b();
        for (int ii = 0; ii < 3; ii++)
        {
            hdo->property.parall.pt[ii].x = hmem->read4b();
            hdo->property.parall.pt[ii].y = hmem->read4b();
        }
        common_size += 32;
    }
    else
        SetHdoParallRgn(hdo, hdo->extent.w, hdo->extent.h);

// read gradient property 28 bytes
    if ((size >= common_size + 28) &&
        (hdo->property.flag & HWPDO_FLAG_GRADATION))
    {
        hdo->property.fromcolor = hmem->read4b();
        hdo->property.tocolor = hmem->read4b();
        hdo->property.gstyle = hmem->read4b();
        hdo->property.angle = hmem->read4b();
        hdo->property.center_x = hmem->read4b();
        hdo->property.center_y = hmem->read4b();
        hdo->property.nstep = hmem->read4b();
        common_size += 28;
    }

// read bitmap property 278 bytes
    if ((size >= common_size + 278) && \
        (hdo->property.flag & HWPDO_FLAG_BITMAP))
    {
        hdo->property.offset1.x = hmem->read4b();
        hdo->property.offset1.y = hmem->read4b();
        hdo->property.offset2.x = hmem->read4b();
        hdo->property.offset2.y = hmem->read4b();
        if (!hmem->readBlock(hdo->property.szPatternFile, 261))
            return FALSE;
        hdo->property.pictype = sal::static_int_cast<char>(hmem->read1b());
        common_size += 278;
    }
	 if( ( size >= common_size + 3 ) && ( hdo->property.flag & HWPDO_FLAG_WATERMARK ) )
	 //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
	 {
		  if( size - common_size >= 5 )
			  hmem->skipBlock( 2 );
		 hdo->property.luminance = hmem->read1b();
		 hdo->property.contrast = hmem->read1b();
		 hdo->property.greyscale = hmem->read1b();
		 common_size += 5;
	 }
	else{
		 hdo->property.luminance = 0;
		 hdo->property.contrast = 0;
		 hdo->property.greyscale = 0;
	}
	 hdo->property.pPara = 0L;

	 if( ( size > common_size ) && (hdo->property.flag & HWPDO_FLAG_AS_TEXTBOX) )
	 {
		  hmem->skipBlock(8);
		  hdo->property.pPara = LoadParaList();
		  if( hdo->property.pPara )
				return TRUE;
		  else
				return FALSE;
	 }

	 if( size <= common_size )
		  return TRUE;
	 return hmem->skipBlock(size - common_size ) != 0;
}


static HWPDrawingObject *LoadDrawingObject(void)
{
    HWPDrawingObject *hdo, *head, *prev;
    int res;

    WORD link_info;

    head = prev = NULL;
    do
    {
        if ((hdo = new HWPDrawingObject) == NULL)
        {
            goto error;
        }
        if (!LoadCommonHeader(hdo, &link_info))
        {
            goto error;
        }
        if (hdo->type < 0 || hdo->type >= HWPDO_NITEMS)
        {
            hdo->type = HWPDO_RECT;
            if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK))
            {
                goto error;
            }
        }
        else
        {
            switch (res = HWPDOFunc(hdo, OBJFUNC_LOAD, NULL, 0))
            {
                case OBJRET_FILE_ERROR:
                    goto error;
                case OBJRET_FILE_OK:
                    break;
                case OBJRET_FILE_NO_PRIVATE_BLOCK:
                case OBJRET_FILE_NO_PRIVATE_BLOCK_2:
                    if (!SkipPrivateBlock(res))
                        goto error;
                    break;
            }
        }
        if (link_info & HDOFILE_HAS_CHILD)
        {
            hdo->child = LoadDrawingObject();
            if (hdo->child == NULL)
            {
                goto error;
            }
        }
        if (prev == NULL)
            head = hdo;
        else
            prev->next = hdo;
        prev = hdo;
    }
    while (link_info & HDOFILE_HAS_NEXT);

    return head;
    error:
// drawing object can be list.
// hdo = current item, head = list;

    if (hdo != NULL)
    {
        HWPDOFunc(hdo, OBJFUNC_FREE, NULL, 0);
        delete hdo;
    }
    if( prev )
    {
        prev->next = NULL;
        return head;
    }
    else
        return 0;
}


static bool LoadDrawingObjectBlock(Picture * pic)
{
    int size = hmem->read4b();

    if (hmem->state() || size < HDOFILE_HEADER_SIZE)
        return false;

    pic->picinfo.picdraw.zorder = hmem->read4b();
    pic->picinfo.picdraw.mbrcnt = hmem->read4b();
    pic->picinfo.picdraw.vrect.x = hmem->read4b();
    pic->picinfo.picdraw.vrect.y = hmem->read4b();
    pic->picinfo.picdraw.vrect.w = hmem->read4b();
    pic->picinfo.picdraw.vrect.h = hmem->read4b();

    if (size > HDOFILE_HEADER_SIZE &&
        !hmem->skipBlock(size - HDOFILE_HEADER_SIZE))
        return false;

    pic->picinfo.picdraw.hdo = LoadDrawingObject();
    if (pic->picinfo.picdraw.hdo == 0)
        return false;
    return true;
}


// object manipulation function

static int
HWPDODefaultFunc(int , HWPDrawingObject * , int cmd, void *, int)
{
    if (cmd == OBJFUNC_LOAD)
        return OBJRET_FILE_NO_PRIVATE_BLOCK;
    return true;
}


// arrow polygon

/* os 06.09.2005: unused function
static void
calcArrowPolygonPts(long lWidth, ZZPoint * arrowPt,
ZZPoint * boxPt, int x1, int y1, int x2, int y2)
{
    long lLength = lWidth;
    int dx, dy;

#if 0
    if (gc->lineWidth > ONE_MILI)
        lWidth = lLength = DRPX2(gc->lineWidth) * 2;
    else
        lWidth = lLength = DRPX2(ARROW_WIDTH);
#endif

    dx = x1 - x2;
    dy = y1 - y2;

    if (dx == 0)
    {
        arrowPt[0].x = x1;
        boxPt[3].x = boxPt[0].x = arrowPt[1].x = x1 + lWidth;
        boxPt[2].x = boxPt[1].x = arrowPt[2].x = x1 - lWidth;
        if (y1 > y2)
        {
            boxPt[2].y = boxPt[3].y = y1 + lLength * 2 / 3;
            arrowPt[0].y = y1 + lLength * 3 / 2;
            boxPt[0].y = boxPt[1].y = arrowPt[1].y = arrowPt[2].y = y1 - lLength;
        }
        else
        {
            boxPt[0].y = boxPt[1].y = y1 - lLength * 2 / 3;
            arrowPt[0].y = y1 - lLength * 3 / 2;
            boxPt[2].y = boxPt[3].y = arrowPt[1].y = arrowPt[2].y = y1 + lLength;
        }
        return;
    }

    double rSlope, rRadians;
    long DX1, DY1, DX2, DY2;

    rSlope = (double) dy / (double) dx;
    rRadians = atan(rSlope);
    DX1 = (long) (lLength * cos(rRadians) + 0.5);
    DY1 = (long) (lLength * sin(rRadians) + 0.5);
    DX2 = (long) (lWidth * sin(rRadians) + 0.5);
    DY2 = (long) (lWidth * cos(rRadians) + 0.5);

    if (dx > 0)
    {
        arrowPt[0].x = (int) (x1 + cos(rRadians) * lLength * 3 / 2);
        arrowPt[0].y = (int) (y1 + sin(rRadians) * lLength * 3 / 2);
        boxPt[0].x = arrowPt[1].x = x1 - DX1 - DX2;
        boxPt[0].y = arrowPt[1].y = y1 - DY1 + DY2;
        boxPt[1].x = arrowPt[2].x = x1 - DX1 + DX2;
        boxPt[1].y = arrowPt[2].y = y1 - DY1 - DY2;
        boxPt[2].x = arrowPt[0].x - DX1 + DX2;
        boxPt[2].y = arrowPt[0].y - DY1 - DY2;
        boxPt[3].x = arrowPt[0].x - DX1 - DX2;
        boxPt[3].y = arrowPt[0].y - DY1 + DY2;
    }
    else
    {
        arrowPt[0].x = (int) (x1 - cos(rRadians) * lLength * 3 / 2);
        arrowPt[0].y = (int) (y1 - sin(rRadians) * lLength * 3 / 2);
        boxPt[0].x = arrowPt[1].x = x1 + DX1 - DX2;
        boxPt[0].y = arrowPt[1].y = y1 + DY1 + DY2;
        boxPt[1].x = arrowPt[2].x = x1 + DX1 + DX2;
        boxPt[1].y = arrowPt[2].y = y1 + DY1 - DY2;
        boxPt[3].x = arrowPt[0].x + DX1 - DX2;
        boxPt[3].y = arrowPt[0].y + DY1 + DY2;
        boxPt[2].x = arrowPt[0].x + DX1 + DX2;
        boxPt[2].y = arrowPt[0].y + DY1 - DY2;
    }
}
*/

static int
HWPDOLineFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
{
    switch (cmd)
    {
        case OBJFUNC_LOAD:
            if (ReadSizeField(4) < 4)
                return OBJRET_FILE_ERROR;
            hdo->u.line_arc.flip = hmem->read4b();
            if (hmem->state())
                return OBJRET_FILE_ERROR;
            if (!SkipUnusedField())
                return OBJRET_FILE_ERROR;
            return OBJRET_FILE_NO_PRIVATE_BLOCK_2;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


// rectangle

static int
HWPDORectFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
{
	return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
}


// ellipse

static int
HWPDOEllipseFunc(int type, HWPDrawingObject * hdo,
int cmd, void *argp, int argv)
{
    return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
}

#define WTMM(x)     ((double)(x) / 1800. * 25.4)
static int
HWPDOEllipse2Func(int type, HWPDrawingObject * hdo,
int cmd, void *argp, int argv)
{
    switch (cmd)
    {
        case OBJFUNC_LOAD:
            if (ReadSizeField(16) < 16)
                return OBJRET_FILE_ERROR;
            hdo->u.arc.radial[0].x = hmem->read4b();
            hdo->u.arc.radial[0].y = hmem->read4b();
            hdo->u.arc.radial[1].x = hmem->read4b();
            hdo->u.arc.radial[1].y = hmem->read4b();

            if (ReadSizeField(0) < 0)
                return OBJRET_FILE_ERROR;
            break;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


// arc

static int
HWPDOArcFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
{
// TRACE("arc");
    switch (cmd)
    {
        case OBJFUNC_LOAD:
            if (ReadSizeField(4) < 4)
                return OBJRET_FILE_ERROR;
            hdo->u.line_arc.flip = hmem->read4b();
            if (hmem->state())
                return OBJRET_FILE_ERROR;
            if (!SkipUnusedField())
                return OBJRET_FILE_ERROR;
            break;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


static int
HWPDOArc2Func(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
{
// TRACE("arc2");
    switch (cmd)
    {
        case OBJFUNC_LOAD:
            return OBJRET_FILE_NO_PRIVATE_BLOCK;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


// freeform

#define SPLINE_NSTEP    100
#define SPLINE_UNIT 20
#define SPLINE_UNIT2    40
#define SPLINE_UNIT3    60

/* os 06.09.2005: unused function
static int getBlend(int alpha)
{
    static bool first = true;
    static char isCached[SPLINE_NSTEP];
    static int blend[SPLINE_NSTEP];
    double ntheta;

    if (first)
    {
        memset(isCached, 0, sizeof(char) * SPLINE_NSTEP);

        first = FALSE;
    }
    if ((alpha < -SPLINE_UNIT2) || (alpha > SPLINE_UNIT2))
        return 0;

    if (!isCached[alpha + SPLINE_UNIT2])
    {
        isCached[alpha + SPLINE_UNIT2] = TRUE;
        ntheta = (double) alpha / SPLINE_UNIT;

        if ((alpha < -SPLINE_UNIT) || (alpha > SPLINE_UNIT))
        {
            ntheta = (ntheta > 1) ? (2 - ntheta) : (2 + ntheta);
            blend[alpha + SPLINE_UNIT2] =
                (int) (1000 * ntheta * ntheta * ntheta / 6.);
        }
        else if (alpha <= 0)
            blend[alpha + SPLINE_UNIT2] =
                    (int) (1000 *
                    (4 - 6 * ntheta * ntheta -
                    3 * ntheta * ntheta * ntheta) / 6);
        else
            blend[alpha + SPLINE_UNIT2] =
                (int) (1000 *
                (4 - 6 * ntheta * ntheta +
                3 * ntheta * ntheta * ntheta) / 6);
    }
    return blend[alpha + SPLINE_UNIT2];
}
*/


static int
HWPDOFreeFormFunc(int type, HWPDrawingObject * hdo,
int cmd, void *argp, int argv)
{
    switch (cmd)
    {
        case OBJFUNC_LOAD:
        {
            hdo->u.freeform.pt = 0;
            if (ReadSizeField(4) < 4)
                return OBJRET_FILE_ERROR;
            hdo->u.freeform.npt = hmem->read4b();
            if (hmem->state())
                return OBJRET_FILE_ERROR;
            if (!SkipUnusedField())
                return OBJRET_FILE_ERROR;

            int size = hdo->u.freeform.npt * sizeof(ZZPoint);

            if (ReadSizeField(size) < size)
                return OBJRET_FILE_ERROR;
            if (hdo->u.freeform.npt)
            {
                hdo->u.freeform.pt =
                    ::comphelper::newArray_null<ZZPoint>(hdo->u.freeform.npt);
                if (hdo->u.freeform.pt == NULL)
                {
                    hdo->u.freeform.npt = 0;
                    return OBJRET_FILE_ERROR;
                }
                for (int ii = 0; ii < hdo->u.freeform.npt; ii++)
                {
                    hdo->u.freeform.pt[ii].x = hmem->read4b();
                    hdo->u.freeform.pt[ii].y = hmem->read4b();
                    if (hmem->state())
                    {
                        delete[]hdo->u.freeform.pt;
                        hdo->u.freeform.npt = 0;
                        return OBJRET_FILE_ERROR;
                    }
                }
            }
            if (!SkipUnusedField())
                return OBJRET_FILE_ERROR;
            return OBJRET_FILE_OK;
        }
        case OBJFUNC_FREE:
            if (hdo->u.freeform.pt)
                delete[]hdo->u.freeform.pt;
            break;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


// text box

static void FreeParaList(HWPPara * para)
{
    if (para->Next())
        FreeParaList(para->Next());
    delete para;
}


static HWPPara *LoadParaList()
{
    if (!hmem)
        return 0;

    HWPFile *hwpf = GetCurrentDoc();
    HIODev *hio = hwpf->SetIODevice(hmem);

    LinkedList < HWPPara > plist;

    hwpf->ReadParaList(plist);
    hwpf->SetIODevice(hio);

    return plist.count()? plist.first() : 0;
}


static int
HWPDOTextBoxFunc(int type, HWPDrawingObject * hdo,
int cmd, void *argp, int argv)
{
// TRACE("textbox");
//    hunit sx, sy, xs, ys;

    switch (cmd)
    {
        case OBJFUNC_LOAD:
            if (ReadSizeField(0) < 0 || !SkipUnusedField())
                return OBJRET_FILE_ERROR;
            if (ReadSizeField(0) < 0)
                return OBJRET_FILE_ERROR;
            hdo->u.textbox.h = LoadParaList();
            return hdo->u.textbox.h ? OBJRET_FILE_OK : OBJRET_FILE_ERROR;
        case OBJFUNC_FREE:
            if (hdo->u.textbox.h)
            {
                FreeParaList(hdo->u.textbox.h);
                hdo->u.textbox.h = NULL;
            }
            break;
        default:
            return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
    }
    return true;
}


static int
HWPDOContainerFunc(int type, HWPDrawingObject * hdo,
int cmd, void *argp, int argv)
{
    return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
}


/* HWPDrawObject 멤버 함수 */

HWPDrawingObject::HWPDrawingObject()
{
    memset(this, 0, sizeof(HWPDrawingObject));
    index = ++count;
}


HWPDrawingObject::~HWPDrawingObject()
{
#if 0
    if (hdo->property.pictype == PICTYP_EMBED)
        RemoveEmbeddedPic(hdo->property.szPatternFile);
    hdo->property.szPatternFile[0] = 0;
#endif
    if (child)
        delete child;

    if (next)
        delete next;

    HWPDOFunc(this, OBJFUNC_FREE, NULL, 0);
}
#endif
