/* Modified by Yen-Ju Chen */ /* CEViewLayoutManager.m Copyright (C) 2002, 2003 Free Software Foundation, Inc. Author: Alexander Malmberg Date: November 2002 - February 2003 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "CEViewTypesetter.h" #include "CEViewLayoutManager.h" #include #include /***** Glyph handling *****/ @implementation CEViewLayoutManager (backend) /* Remove ligature support (backart) */ -(unsigned int) _findSafeBreakMovingBackwardFrom: (unsigned int)ch { return ch; } -(unsigned int) _findSafeBreakMovingForwardFrom: (unsigned int)ch { return ch; } -(void) _generateGlyphsForRun: (glyph_run_t *)run at: (unsigned int)pos { run->ligature = 0; [super _generateGlyphsForRun: run at: pos]; } @end /***** Layout handling *****/ @implementation CEViewLayoutManager (layout) - (void) setTextContainer: (NSTextContainer *)aTextContainer forGlyphRange: (NSRange)glyphRange { textcontainer_t *tc; int i; tc = textcontainers; i = 0; /* FIXME: Only set text container once for whole glyphs*/ tc->pos = 0; tc->length = glyphRange.length; layout_glyph = tc->pos + tc->length; if (layout_glyph == glyphs->glyph_length) layout_char = glyphs->char_length; else layout_char = [self characterIndexForGlyphAtIndex: layout_glyph]; } - (void) setLineFragmentRect: (NSRect)fragmentRect forGlyphRange: (NSRange)glyphRange usedRect: (NSRect)usedRect { textcontainer_t *tc; int i; linefrag_t *lf; tc = textcontainers; i = 0; lf = &tc->linefrags[tc->num_linefrags - 1]; if (!(tc->num_linefrags + tc->num_soft)) { if (!tc->size_linefrags) { tc->size_linefrags = 16; tc->linefrags = malloc(sizeof(linefrag_t) * tc->size_linefrags); } tc->num_linefrags = 1; lf = tc->linefrags; } else if (!tc->num_soft) { if (tc->size_linefrags <= tc->num_linefrags) { tc->size_linefrags += tc->size_linefrags / 2; tc->linefrags = realloc(tc->linefrags, sizeof(linefrag_t) * tc->size_linefrags); } tc->num_linefrags++; lf = &tc->linefrags[tc->num_linefrags - 1]; } else { int i; for (i = tc->num_linefrags, lf = tc->linefrags + i; i < tc->num_linefrags + tc->num_soft; i++, lf++) { if (lf->pos >= NSMaxRange(glyphRange)) break; if (lf->points) { free(lf->points); lf->points = NULL; } } if (i == tc->num_linefrags) { /* If we should keep all soft frags, we need to enlarge the array to fit the new line frag. */ if (tc->size_linefrags <= tc->num_linefrags + tc->num_soft) { tc->size_linefrags += tc->size_linefrags / 2; tc->linefrags = realloc(tc->linefrags, sizeof(linefrag_t) * tc->size_linefrags); } memmove(&tc->linefrags[tc->num_linefrags + 1], &tc->linefrags[tc->num_linefrags], tc->num_soft * sizeof(linefrag_t)); } else if (i > tc->num_linefrags + 1) { tc->num_soft -= i - tc->num_linefrags; memmove(&tc->linefrags[tc->num_linefrags + 1], &tc->linefrags[i], tc->num_soft * sizeof(linefrag_t)); } else { /* If i == tc->num_linefrags + 1, we're lucky and everything already lines up, so no moving is necessary. */ tc->num_soft--; } tc->num_linefrags++; lf = &tc->linefrags[tc->num_linefrags - 1]; } memset(lf, 0, sizeof(linefrag_t)); lf->rect = fragmentRect; lf->used_rect = usedRect; lf->pos = glyphRange.location; lf->length = glyphRange.length; } - (void) setLocation: (NSPoint)location forStartOfGlyphRange: (NSRange)glyphRange { textcontainer_t *tc; int i; linefrag_t *lf; linefrag_point_t *lp; i = 0; tc = textcontainers; for (i = tc->num_linefrags - 1, lf = tc->linefrags + i; i >= 0; i--, lf--) { if (lf->pos <= glyphRange.location && lf->pos + lf->length >= glyphRange.location + glyphRange.length) break; } if (!lf->num_points) { lp = lf->points = malloc(sizeof(linefrag_point_t)); lf->num_points++; } else { lp = &lf->points[lf->num_points - 1]; lf->num_points++; lf->points = realloc(lf->points, sizeof(linefrag_point_t) * lf->num_points); lp = &lf->points[lf->num_points - 1]; } lp->pos = glyphRange.location; lp->length = glyphRange.length; lp->p = location; } @end /***** The rest *****/ @implementation CEViewLayoutManager - (id) init { if (!(self = [super init])) return nil; typesetter = [[CEViewTypesetter sharedSystemTypesetter] retain]; return self; } -(void) dealloc { DESTROY(typesetter); [super dealloc]; } @end