/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // A method to extend a strip in a given direction, starting from a given face /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Input : face, the starting face // oldest, middle, the two first indices of the strip == a starting edge == a direction // Output : strip, a buffer to store the strip // faces, a buffer to store the faces of the strip // tags, a buffer to mark the visited faces // Return : u32, the strip length // Exception: - // Remark : - u32 Striper::TrackStrip(u32 face, u32 oldest, u32 middle, u32* strip, u32* faces, bool* tags) { u32 Length = 2; // Initial length is 2 since we have 2 indices in input strip[0] = oldest; // First index of the strip strip[1] = middle; // Second index of the strip bool DoTheStrip = true; while(DoTheStrip) { u32 Newest = mAdj->mFaces[face].OppositeVertex(oldest, middle); // Get the third index of a face given two of them strip[Length++] = Newest; // Extend the strip,... *faces++ = face; // ...keep track of the face,... tags[face] = true; // ...and mark it as "done". u8 CurEdge = mAdj->mFaces[face].FindEdge(middle, Newest); // Get the edge ID... u32 Link = mAdj->mFaces[face].ATri[CurEdge]; // ...and use it to catch the link to adjacent face. if(IS_BOUNDARY(Link)) DoTheStrip = false; // If the face is no more connected, we're done... else { face = MAKE_ADJ_TRI(Link); // ...else the link gives us the new face index. if(tags[face]) DoTheStrip=false; // Is the new face already done? } oldest = middle; // Shift the indices and wrap middle = Newest; } return Length; }
static void FILL_FUNCTION(gfxr_pic_t *pic, int x_320, int y_200, int color, int priority, int control, int drawenable, int sci_titlebar_size) { int linewidth = pic->mode->xfact * 320; int x, y; int xl, xr; int ytotal; int bitmask; byte *bounds = NULL; int legalcolor, legalmask; #ifdef DRAW_SCALED int min_x, min_y, max_x, max_y; #endif int original_drawenable = drawenable; // Backup, since we need the unmodified value // for filling the aux and control map // Restrict drawenable not to restrict itself to zero if (pic->control_map->index_data[y_200 * 320 + x_320] != 0) drawenable &= ~GFX_MASK_CONTROL; if (color == 0xff) drawenable &= ~GFX_MASK_VISUAL; if (priority == 0) { drawenable &= ~GFX_MASK_PRIORITY; original_drawenable &= ~GFX_MASK_PRIORITY; } AUXBUF_FILL(pic, x_320, y_200, original_drawenable, (drawenable & GFX_MASK_CONTROL) ? control : 0, sci_titlebar_size); #ifdef DRAW_SCALED _gfxr_auxbuf_spread(pic, &min_x, &min_y, &max_x, &max_y); if (_gfxr_find_fill_point(pic, min_x, min_y, max_x, max_y, x_320, y_200, color, drawenable, &x, &y)) { //GFXWARN("Could not find scaled fill point, but unscaled fill point was available!\n"); drawenable &= GFX_MASK_PRIORITY; if (!drawenable) _gfxr_auxbuf_propagate_changes(pic, 0); } #else x = x_320; y = y_200; #endif ytotal = y * linewidth; if (!drawenable) return; if (drawenable & GFX_MASK_VISUAL) { bounds = pic->visual_map->index_data; #if 0 // Code disabled, as removing it fixes qg1 pic.095 (unscaled). However, // it MAY be of relevance to scaled pic drawing... if ((color & 0xf) == 0xf // When dithering with white, do more // conservative checks || (color & 0xf0) == 0xf0) legalcolor = 0xff; else legalcolor = 0xf0; // Only check the second color #endif #ifdef DRAW_SCALED legalcolor = 0xff; legalmask = legalcolor; #else legalmask = 0x0ff0; legalcolor = 0xff; #endif } else if (drawenable & GFX_MASK_PRIORITY) { bounds = pic->priority_map->index_data; legalcolor = 0; legalmask = 0x0f0f; } else { legalcolor = 0; legalmask = 0x0f0f; } if (!bounds || IS_BOUNDARY(x, y, bounds[ytotal + x])) return; if (bounds) { #ifdef DRAW_SCALED int proj_y = y_200; int proj_ytotal = proj_y * 320; int proj_x = x_320; int proj_xl_bound; int proj_xr_bound; int proj_xl, proj_xr; ytotal = y * linewidth; proj_xl_bound = proj_x; if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { while (proj_xl_bound && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT)) --proj_xl_bound; } else while (proj_xl_bound < 319 && SCALED_CHECK(!(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT))) ++proj_xl_bound; proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x; while ((proj_xr_bound < 319) && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT)) ++proj_xr_bound; proj_xl = proj_xl_bound; proj_xr = proj_xr_bound; proj_xl_bound *= pic->mode->xfact; if (proj_xl_bound) proj_xl_bound -= pic->mode->xfact - 1; if (proj_xr_bound < 319) ++proj_xr_bound; proj_xr_bound *= pic->mode->xfact; proj_xr_bound += pic->mode->xfact - 1; #endif xl = x; while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y, bounds[ytotal + xl -1]))) --xl; while (x < proj_xr_bound && (!IS_BOUNDARY(x + 1, y, bounds[ytotal + x + 1]))) ++x; xr = x; if (drawenable & GFX_MASK_VISUAL) memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1); if (drawenable & GFX_MASK_PRIORITY) memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1); FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, -1, bounds, legalcolor, legalmask, color, priority, drawenable, sci_titlebar_size); FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, + 1, bounds, legalcolor, legalmask, color, priority, drawenable, sci_titlebar_size); } // Now finish the aux buffer bitmask = drawenable & (((color != 0xff) ? 1 : 0) | ((priority) ? 2 : 0) | ((control) ? 4 : 0)); #ifdef DRAW_SCALED # ifdef FILL_RECURSIVE_DEBUG if (fillmagc) # endif _gfxr_auxbuf_propagate_changes(pic, bitmask); #endif }
static void FILL_FUNCTION_RECURSIVE(gfxr_pic_t *pic, int old_xl, int old_xr, int y, int dy, byte *bounds, int legalcolor, int legalmask, int color, int priority, int drawenable, int sci_titlebar_size) { int linewidth = pic->mode->xfact * 320; int miny = pic->mode->yfact * sci_titlebar_size; int maxy = pic->mode->yfact * 200; int xl, xr; int oldytotal = y * linewidth; #ifdef DRAW_SCALED int old_proj_y = -42; int proj_y; int proj_ytotal; int proj_x; int proj_xl_bound = 0; int proj_xr_bound = 0; #endif do { int ytotal = oldytotal + (linewidth * dy); int xcont; int state; y += dy; #ifdef FILL_RECURSIVE_DEBUG if (!fillc) return; else if (!fillmagc) { --fillc; } #endif if (y < miny || y >= maxy) { PRINT_DEBUG0("ABRT on failed initial assertion!\n"); return; } #ifdef DRAW_SCALED proj_y = y / pic->mode->yfact; if (proj_y != old_proj_y) { // First, find the projected coordinates, unless known already: proj_ytotal = proj_y * 320; proj_x = old_xl / pic->mode->xfact; proj_xl_bound = proj_x; if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { while (proj_xl_bound && pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT) --proj_xl_bound; } else { while (proj_xl_bound < 319 && !(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT)) ++proj_xl_bound; if (proj_xl_bound < 319) ++proj_xl_bound; } if (proj_xl_bound == 319 && !(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { PRINT_DEBUG0("ABRT because proj_xl_bound couldn't be found\n"); return; } proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x; while ((proj_xr_bound < 319) && pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT) ++proj_xr_bound; #ifdef FILL_RECURSIVE_DEBUG if (!fillmagc) { fprintf(stderr, "l%d: {%d,%d} | ", proj_y, proj_xl_bound, proj_xr_bound); pic->aux_map[proj_y*320 + proj_xl_bound] |= 0x2; pic->aux_map[proj_y*320 + proj_xr_bound] |= 0x2; } #endif proj_xl_bound *= pic->mode->xfact; if (proj_xl_bound) proj_xl_bound -= pic->mode->xfact - 1; if (proj_xr_bound < 319) ++proj_xr_bound; proj_xr_bound *= pic->mode->xfact; proj_xr_bound += pic->mode->xfact - 1; old_proj_y = proj_y; } #else # define proj_xl_bound 0 # define proj_xr_bound 319 #endif // Now we have the projected limits, get the real ones: xl = (old_xl > proj_xl_bound) ? old_xl : proj_xl_bound; if (!IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) { // go left as far as possible while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y + 1, bounds[ytotal + xl - 1]))) --xl; } else // go right until the fillable area starts while (xl < proj_xr_bound && (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl]))) ++xl; PRINT_DEBUG1("<%d,", xl); if ((xl > proj_xr_bound) || (xl > old_xr)) { PRINT_DEBUG0("ABRT because xl > xr_bound\n"); return; } xr = (xl > old_xl) ? xl : old_xl; while (xr < proj_xr_bound && (!IS_BOUNDARY(xr + 1, y + 1, bounds[ytotal + xr + 1]))) ++xr; PRINT_DEBUG1("%d> -> ", xr); if (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) { PRINT_DEBUG0("ABRT because xl illegal\n"); return; } #ifdef DRAW_SCALED PRINT_DEBUG4("[%d[%d,%d]%d]\n", proj_xl_bound, xl, xr, proj_xr_bound); if (xl < proj_xl_bound && xr - 3*pic->mode->xfact < proj_xl_bound) { PRINT_DEBUG0("ABRT interval left of zone\n"); return; } if (xr > proj_xr_bound && xl + 3*pic->mode->xfact > proj_xr_bound) { PRINT_DEBUG0("ABRT because interval right of zone\n"); return; } #endif if (drawenable & GFX_MASK_VISUAL) memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1); if (drawenable & GFX_MASK_PRIORITY) memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1); // Check whether we need to recurse on branches in the same direction state = 0; xcont = xr + 1; while (xcont <= old_xr) { if (IS_BOUNDARY(xcont, y + 1, bounds[ytotal + xcont])) state = xcont; else if (state) { // recurse PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); PRINT_DEBUG4("rec BRANCH %d [%d,%d] l%d\n", dy, state, xcont, y - dy); FILL_FUNCTION_RECURSIVE(pic, state, xcont, y - dy, dy, bounds, legalcolor, legalmask, color, priority, drawenable, sci_titlebar_size); state = 0; } ++xcont; } // Check whether we need to recurse on backward branches: // left if (xl < old_xl - 1) { state = 0; for (xcont = old_xl - 1; xcont >= xl; xcont--) { if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont])) state = xcont; else if (state) { // recurse PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); PRINT_DEBUG4("rec BACK-LEFT %d [%d,%d] l%d\n", -dy, state, xcont, y); FILL_FUNCTION_RECURSIVE(pic, xcont, state, y, -dy, bounds, legalcolor, legalmask, color, priority, drawenable, sci_titlebar_size); state = 0; } } } // right if (xr > old_xr + 1) { state = 0; for (xcont = old_xr + 1; xcont <= xr; xcont++) { if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont])) state = xcont; else if (state) { // recurse PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); PRINT_DEBUG4("rec BACK-RIGHT %d [%d,%d] l%d\n", -dy, state, xcont, y); FILL_FUNCTION_RECURSIVE(pic, state, xcont, y, -dy, bounds, legalcolor, legalmask, color, priority, drawenable, sci_titlebar_size); state = 0; } } } oldytotal = ytotal; old_xl = xl; old_xr = xr; } while (1); }
/** * Set the boundary conditions depending on the chosen model */ void boundaryvalues( int imax, int jmax, double dx, double dy, double **U, double **V, double **K, double **W, double nu, int *b, int **Flag ) { int i, j; int c, bound_now; for( c = 0; c < 4; c++ ){ bound_now = b[c]; /* treating different cases of boundaries * inflow treated separately * */ switch(bound_now){ case 1: no_slip( imax, jmax, U, V, K, W, c,dx,dy,nu); break; case 3: outflow( imax, jmax, U, V, K, W, c); break; default: free_slip( imax, jmax, U, V, K, W, c); break; } } /* Boundary conditions for the obstacle cells */ for( i = 1; i <= imax; i++ ) for( j = 1; j <= jmax; j++ ) if( IS_BOUNDARY(Flag[i][j]) ){ /* Boundary conditions for obstacles with North-Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_NE ) == B_NE ){ U[ i ][ j ] = .0; V[ i ][ j ] = .0; U[ i-1 ][ j ] = -U[ i-1 ][ j+1 ]; V[ i ][ j-1 ] = -V[ i+1 ][ j-1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 0.5*( 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) + 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ); } else /* Boundary conditions for obstacles with North-Western fluid cell */ if( ( Flag[ i ][ j ] & B_NW ) == B_NW ){ U[ i-1 ][ j ] = .0; V[ i ][ j ] = .0; U[ i ][ j ] = -U[ i ][ j+1 ]; V[ i ][ j-1 ] = -V[ i-1 ][ j-1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 0.5*( 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) + 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ); } else /* Boundary conditions for obstacles with South-Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_SE ) == B_SE ){ U[ i ][ j ] = .0; V[ i ][ j-1 ] = .0; U[ i-1 ][ j ] = -U[ i-1 ][ j-1 ]; V[ i ][ j ] = -V[ i+1 ][ j ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 0.5*( 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) + 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ); } else /* Boundary conditions for obstacles with South-Western fluid cell */ if( ( Flag[ i ][ j ] & B_SW ) == B_SW ){ U[ i-1 ][ j ] = .0; V[ i ][ j-1 ] = .0; U[ i ][ j ] = -U[ i ][ j-1 ]; V[ i ][ j ] = -V[ i-1 ][ j ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 0.5*( 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) + 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ); } else /* Boundary conditions for obstacles with Northern fluid cell */ if( ( Flag[ i ][ j ] & B_N ) == B_N ){ V[ i ][ j ] = .0; U[ i ][ j ] = -U[ i ][ j+1 ]; U[ i-1 ][ j ] = -U[ i-1 ][ j+1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) ; } else /* Boundary conditions for obstacles with Southern fluid cell */ if(( Flag[ i ][ j ] & B_S ) == B_S ){ V[ i ][ j-1 ] = .0; U[ i ][ j ] = -U[ i ][ j-1 ]; U[ i-1 ][ j ] = -U[ i-1 ][ j-1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 6.0*10.0*nu/(beta_1*SQ(0.5*dy)) ; }else /* Boundary conditions for obstacles with Western fluid cell */ if( ( Flag[ i ][ j ] & B_W ) == B_W ){ U[ i-1 ][ j ] = .0; V[ i ][ j ] = -V[ i-1 ][ j ]; V[ i ][ j-1 ] = -V[ i-1 ][ j-1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ; } else /* Boundary conditions for obstacles with Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_E ) == B_E ){ U[ i ][ j ] = .0; V[ i ][ j ] = -V[ i+1 ][ j ]; V[ i ][ j-1 ] = -V[ i+1 ][ j-1 ]; K[ i ][ j ] = 0.00001; W[ i ][ j ] = 6.0*10.0*nu/(beta_1*SQ(0.5*dx)) ; } } }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // A method to create the triangle strips /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Input : result, the result structure // Output : - // Return : true if success // Exception: - // Remark : - bool Striper::Compute(STRIPERRESULT& result) { // You must call Init() first if(!mAdj) return false; // Get some bytes mStripLengths = new CustomArray; if(!mStripLengths) return false; mStripRuns = new CustomArray; if(!mStripRuns) return false; mTags = new bool[mAdj->mNbFaces]; if(!mTags) return false; u32* Connectivity = new u32[mAdj->mNbFaces]; if(!Connectivity) return false; // mTags contains one bool/face. True=>the face has already been included in a strip memset(mTags, 0, mAdj->mNbFaces*sizeof(bool)); // Compute the number of connections for each face. This buffer is further recycled into // the insertion order, ie contains face indices in the order we should treat them memset(Connectivity, 0, mAdj->mNbFaces*sizeof(u32)); if(mSGIAlgorithm) { // Compute number of adjacent triangles for each face for(u32 i=0;i<mAdj->mNbFaces;i++) { AdjTriangle* Tri = &mAdj->mFaces[i]; if(!IS_BOUNDARY(Tri->ATri[0])) Connectivity[i]++; if(!IS_BOUNDARY(Tri->ATri[1])) Connectivity[i]++; if(!IS_BOUNDARY(Tri->ATri[2])) Connectivity[i]++; } // Sort by number of neighbors RadixSorter RS; u32* Sorted = RS.Sort(Connectivity, mAdj->mNbFaces).GetIndices(); // The sorted indices become the order of insertion in the strips memcpy(Connectivity, Sorted, mAdj->mNbFaces*sizeof(u32)); } else { // Default order for(u32 i=0;i<mAdj->mNbFaces;i++) Connectivity[i] = i; } mNbStrips = 0; // #strips created u32 TotalNbFaces = 0; // #faces already transformed into strips u32 Index = 0; // Index of first face while(TotalNbFaces!=mAdj->mNbFaces) { // Look for the first face [could be optimized] while(mTags[Connectivity[Index]]) Index++; u32 FirstFace = Connectivity[Index]; // Compute the three possible strips from this face and take the best TotalNbFaces += ComputeBestStrip(FirstFace); // Let's wrap mNbStrips++; } // Free now useless ram RELEASEARRAY(Connectivity); RELEASEARRAY(mTags); // Fill result structure and exit result.NbStrips = mNbStrips; result.StripLengths = (u32*) mStripLengths ->Collapse(); result.StripRuns = mStripRuns ->Collapse(); if(mConnectAllStrips) ConnectAllStrips(result); return true; }
void detectEdgeNodata::processWindow(dimension_type row, dimension_type col, elevation_type &point, elevation_type *a, elevation_type *b, elevation_type *c) { AMI_err ae; static nodataType prevCell; /* cell on left (gets initialized) */ assert(row>=0); assert(col>=0); /* create window and write out */ ElevationWindow win(a, b, c); fillPit(win); /* fill pit in window */ ae = elevStream->write_item(win.get()); assert(ae == AMI_ERROR_NO_ERROR); /* only interested in nodata in this pass */ if(win.get() != nodata) { prevCell.label = LABEL_UNDEF; return; } if(col == 0) prevCell.label = LABEL_UNDEF; /* no left cell */ /* now check for continuing plateaus */ nodataType *ptarr = getNodataForward(row-1, col-1, nr, nc); /* make sure we use boundary label if appropriate */ cclabel_type crtlabel; crtlabel = (IS_BOUNDARY(row,col,nr, nc) ? LABEL_BOUNDARY : LABEL_UNDEF); for(int i=0; i<4; i++) { if(win.get(i) != win.get()) continue; /* only interesting if same elev */ /* determine label for cell */ cclabel_type label = LABEL_UNDEF; if(i<3) { if(ptarr[i].valid) label = ptarr[i].label; } else { if(prevCell.valid) label = prevCell.label; } /* check for collisions */ if(label != LABEL_UNDEF) { if (crtlabel == LABEL_UNDEF) { crtlabel = label; } else if(crtlabel != label) { /* collision!! */ /* pick smaller label, but prefer nodata */ if(crtlabel==LABEL_BOUNDARY || crtlabel<label) { colTree.insert(crtlabel, label); } else { colTree.insert(label, crtlabel); crtlabel = label; } } } } /* assign label if required */ if(crtlabel == LABEL_UNDEF) { crtlabel = labelFactory::getNewLabel(); } /* write this plateau point to the plateau stream */ nodataType pt; prevCell = pt = nodataType(row, col, crtlabel); nodataQueue->enqueue(pt); /* NODATA_DEBUG *stats << "inserting " << pt << endl; */ nodataStream->write_item(pt); /* save to file for later use */ }
static void hangul_engine_shape (PangoEngineShape *engine, PangoFont *font, const char *text, gint length, const PangoAnalysis *analysis, PangoGlyphString *glyphs) { int n_chars = g_utf8_strlen (text, length); int n_glyphs; int i; const char *p, *start; int n_jamos; gunichar prev = 0; n_glyphs = 0; start = p = text; n_jamos = 0; for (i = 0; i < n_chars; i++) { gunichar wc; wc = g_utf8_get_char (p); /* Check syllable boundaries. */ if (n_jamos && IS_BOUNDARY (prev, wc)) { if (n_jamos == 1 && IS_S (prev)) /* common case which the most people use */ render_basic (font, prev, glyphs, &n_glyphs, start - text); else /* possibly complex composition */ render_syllable (font, start, n_jamos, glyphs, &n_glyphs, start - text); n_jamos = 0; start = p; } prev = wc; if (!IS_HANGUL (wc)) { render_basic (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else if (IS_M (wc) && !n_jamos) { /* Tone mark not following syllable */ render_isolated_tone (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else n_jamos++; p = g_utf8_next_char (p); } if (n_jamos == 1 && IS_S (prev)) render_basic (font, prev, glyphs, &n_glyphs, start - text); else if (n_jamos > 0) render_syllable (font, start, n_jamos, glyphs, &n_glyphs, start - text); }
/** * SOR Method */ void sor( double omg, double dx, double dy, int imax, int jmax, const int fluid_cells, double **P, double **RS, int **Flag, double *res, char *problem, double dp ){ int i,j; double rloc; double coeff = omg/(2.0*(1.0/(dx*dx)+1.0/(dy*dy))); /* SOR iteration */ for(i = 1; i <= imax; i++) { for(j = 1; j<=jmax; j++) { /* SOR computation limited to the fluid cells ( C_F - fluid cell )*/ if ( IS_FLUID(Flag[ i ][ j ]) ) P[i][j] = (1.0-omg)*P[i][j] + coeff*(( P[i+1][j]+P[i-1][j])/(dx*dx) + ( P[i][j+1]+P[i][j-1])/(dy*dy) - RS[i][j]); } } /* compute the residual */ rloc = 0; for(i = 1; i <= imax; i++) for(j = 1; j <= jmax; j++) /* Residual computation limited to the fluid cells ( C_F - fluid cell ) */ rloc += (IS_FLUID(Flag[ i ][ j ])) * ( (P[i+1][j]-2.0*P[i][j]+P[i-1][j])/(dx*dx) + ( P[i][j+1]-2.0*P[i][j]+P[i][j-1])/(dy*dy) - RS[i][j])* ( (P[i+1][j]-2.0*P[i][j]+P[i-1][j])/(dx*dx) + ( P[i][j+1]-2.0*P[i][j]+P[i][j-1])/(dy*dy) - RS[i][j]); /* Residual devided only by the number of fluid cells instead of imax*jmax */ rloc = rloc/((double)fluid_cells); rloc = sqrt(rloc); /* set residual */ *res = rloc; /* set homogenous Neumann boundary conditions for pressure in the horizontal walls */ for(i = 1; i <= imax; i++) { P[i][0] = P[i][1]; P[i][jmax+1] = P[i][jmax]; } if (dp!=0){ /* pressure differece driven flow */ for (j=1; j<=jmax; j++){ P[0][j]=2.0*dp-P[1][j]; /* set left pressure dirichlet condition to p_w = dp */ P[imax+1][j]=-P[imax][j]; /* set right pressure dirichlet condition to p_w = 0 */ } } else { /* set homogenous neumann boundary conditions for pressure in the vertical walls */ for(j = 1; j <= jmax; j++) { P[0][j] = P[1][j]; P[imax+1][j] = P[imax][j]; } } /* Boundary conditions for the obstacle cells */ for( i = 1; i <= imax; i++ ){ for( j = 1; j <= jmax; j++ ){ if( IS_BOUNDARY(Flag[i][j])){ /* Boundary conditions for obstacles with North-Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_NE ) == B_NE ){ P[ i ][ j ] = 0.5*( P[ i+1 ][ j ] + P[ i ][ j+1 ] ); } else /* Boundary conditions for obstacles with North-Western fluid cell */ if( ( Flag[ i ][ j ] & B_NW ) == B_NW ){ P[ i ][ j ] = 0.5*( P[ i-1 ][ j ] + P[ i ][ j+1 ] ); } else /* Boundary conditions for obstacles with South-Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_SE ) == B_SE ){ P[ i ][ j ] = 0.5*( P[ i+1 ][ j ] + P[ i ][ j-1 ] ); } else /* Boundary conditions for obstacles with South-Western fluid cell */ if( ( Flag[ i ][ j ] & B_SW ) == B_SW ){ P[ i ][ j ] = 0.5*( P[ i-1 ][ j ] + P[ i ][ j-1 ] ); } else /* Boundary conditions for obstacles with Northern fluid cell */ if( ( Flag[ i ][ j ] & B_N ) == B_N ){ P[ i ][ j ] = P[ i ][ j+1 ]; } else /* Boundary conditions for obstacles with Southern fluid cell */ if( ( Flag[ i ][ j ] & B_S ) == B_S ){ P[ i ][ j ] = P[ i ][ j-1 ]; } else /* Boundary conditions for obstacles with Western fluid cell */ if( ( Flag[ i ][ j ] & B_W ) == B_W ){ P[ i ][ j ] = P[ i-1 ][ j ]; } else /* Boundary conditions for obstacles with Eastern fluid cell */ if( ( Flag[ i ][ j ] & B_E ) == B_E ){ P[ i ][ j ] = P[ i+1 ][ j ]; } } } } }