コード例 #1
1
ファイル: parseHelper.cpp プロジェクト: BaHbKaTX/openjdk
//------------------------------array_store_check------------------------------
// pull array from stack and check that the store is valid
void Parse::array_store_check() {

  // Shorthand access to array store elements
  Node *obj = stack(_sp-1);
  Node *idx = stack(_sp-2);
  Node *ary = stack(_sp-3);

  if (_gvn.type(obj) == TypePtr::NULL_PTR) {
    // There's never a type check on null values.
    // This cutout lets us avoid the uncommon_trap(Reason_array_check)
    // below, which turns into a performance liability if the
    // gen_checkcast folds up completely.
    return;
  }

  // Extract the array klass type
  int klass_offset = oopDesc::klass_offset_in_bytes();
  Node* p = basic_plus_adr( ary, ary, klass_offset );
  // p's type is array-of-OOPS plus klass_offset
  Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) );
  // Get the array klass
  const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr();

  // array_klass's type is generally INexact array-of-oop.  Heroically
  // cast the array klass to EXACT array and uncommon-trap if the cast
  // fails.
  bool always_see_exact_class = false;
  if (MonomorphicArrayCheck
      && !too_many_traps(Deoptimization::Reason_array_check)) {
    always_see_exact_class = true;
    // (If no MDO at all, hope for the best, until a trap actually occurs.)
  }

  // Is the array klass is exactly its defined type?
  if (always_see_exact_class && !tak->klass_is_exact()) {
    // Make a constant out of the inexact array klass
    const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
    Node* con = makecon(extak);
    Node* cmp = _gvn.transform(new (C, 3) CmpPNode( array_klass, con ));
    Node* bol = _gvn.transform(new (C, 2) BoolNode( cmp, BoolTest::eq ));
    Node* ctrl= control();
    { BuildCutout unless(this, bol, PROB_MAX);
      uncommon_trap(Deoptimization::Reason_array_check,
                    Deoptimization::Action_maybe_recompile,
                    tak->klass());
    }
    if (stopped()) {          // MUST uncommon-trap?
      set_control(ctrl);      // Then Don't Do It, just fall into the normal checking
    } else {                  // Cast array klass to exactness:
      // Use the exact constant value we know it is.
      replace_in_map(array_klass,con);
      CompileLog* log = C->log();
      if (log != NULL) {
        log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
                  log->identify(tak->klass()));
      }
      array_klass = con;      // Use cast value moving forward
    }
  }

  // Come here for polymorphic array klasses

  // Extract the array element class
  int element_klass_offset = objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc);
  Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
  Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) );

  // Check (the hard way) and throw if not a subklass.
  // Result is ignored, we just need the CFG effects.
  gen_checkcast( obj, a_e_klass );
}
コード例 #2
0
static int vector3_normalize(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(normalize(stack.get_vector3(1)));
	return 1;
}
コード例 #3
0
static int vector3_forward(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(VECTOR3_FORWARD);
	return 1;
}
コード例 #4
0
static int vector3_equal(lua_State* L)
{
	LuaStack stack(L);
	stack.push_bool(stack.get_vector3(1) == stack.get_vector3(2));
	return 1;
}
コード例 #5
0
static int vector3_squared_length(lua_State* L)
{
	LuaStack stack(L);
	stack.push_float(squared_length(stack.get_vector3(1)));
	return 1;
}
コード例 #6
0
ファイル: RecastMeshDetail.cpp プロジェクト: arrian/3d-engine
/// @par
///
/// See the #rcConfig documentation for more information on the configuration parameters.
///
/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig
bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
						   const float sampleDist, const float sampleMaxError,
						   rcPolyMeshDetail& dmesh)
{
	rcAssert(ctx);
	
	ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL);

	if (mesh.nverts == 0 || mesh.npolys == 0)
		return true;
	
	const int nvp = mesh.nvp;
	const float cs = mesh.cs;
	const float ch = mesh.ch;
	const float* orig = mesh.bmin;
	const int borderSize = mesh.borderSize;
	
	rcIntArray edges(64);
	rcIntArray tris(512);
	rcIntArray stack(512);
	rcIntArray samples(512);
	float verts[256*3];
	rcHeightPatch hp;
	int nPolyVerts = 0;
	int maxhw = 0, maxhh = 0;
	
	rcScopedDelete<int> bounds = (int*)rcAlloc(sizeof(int)*mesh.npolys*4, RC_ALLOC_TEMP);
	if (!bounds)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4);
		return false;
	}
	rcScopedDelete<float> poly = (float*)rcAlloc(sizeof(float)*nvp*3, RC_ALLOC_TEMP);
	if (!poly)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3);
		return false;
	}
	
	// Find max size for a polygon area.
	for (int i = 0; i < mesh.npolys; ++i)
	{
		const unsigned short* p = &mesh.polys[i*nvp*2];
		int& xmin = bounds[i*4+0];
		int& xmax = bounds[i*4+1];
		int& ymin = bounds[i*4+2];
		int& ymax = bounds[i*4+3];
		xmin = chf.width;
		xmax = 0;
		ymin = chf.height;
		ymax = 0;
		for (int j = 0; j < nvp; ++j)
		{
			if(p[j] == RC_MESH_NULL_IDX) break;
			const unsigned short* v = &mesh.verts[p[j]*3];
			xmin = rcMin(xmin, (int)v[0]);
			xmax = rcMax(xmax, (int)v[0]);
			ymin = rcMin(ymin, (int)v[2]);
			ymax = rcMax(ymax, (int)v[2]);
			nPolyVerts++;
		}
		xmin = rcMax(0,xmin-1);
		xmax = rcMin(chf.width,xmax+1);
		ymin = rcMax(0,ymin-1);
		ymax = rcMin(chf.height,ymax+1);
		if (xmin >= xmax || ymin >= ymax) continue;
		maxhw = rcMax(maxhw, xmax-xmin);
		maxhh = rcMax(maxhh, ymax-ymin);
	}
	
	hp.data = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxhw*maxhh, RC_ALLOC_TEMP);
	if (!hp.data)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh);
		return false;
	}
	
	dmesh.nmeshes = mesh.npolys;
	dmesh.nverts = 0;
	dmesh.ntris = 0;
	dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM);
	if (!dmesh.meshes)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4);
		return false;
	}

	int vcap = nPolyVerts+nPolyVerts/2;
	int tcap = vcap*2;

	dmesh.nverts = 0;
	dmesh.verts = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM);
	if (!dmesh.verts)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3);
		return false;
	}
	dmesh.ntris = 0;
	dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char*)*tcap*4, RC_ALLOC_PERM);
	if (!dmesh.tris)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4);
		return false;
	}
	
	for (int i = 0; i < mesh.npolys; ++i)
	{
		const unsigned short* p = &mesh.polys[i*nvp*2];
		
		// Store polygon vertices for processing.
		int npoly = 0;
		for (int j = 0; j < nvp; ++j)
		{
			if(p[j] == RC_MESH_NULL_IDX) break;
			const unsigned short* v = &mesh.verts[p[j]*3];
			poly[j*3+0] = v[0]*cs;
			poly[j*3+1] = v[1]*ch;
			poly[j*3+2] = v[2]*cs;
			npoly++;
		}
		
		// Get the height data from the area of the polygon.
		hp.xmin = bounds[i*4+0];
		hp.ymin = bounds[i*4+2];
		hp.width = bounds[i*4+1]-bounds[i*4+0];
		hp.height = bounds[i*4+3]-bounds[i*4+2];
		getHeightData(chf, p, npoly, mesh.verts, borderSize, hp, stack);
		
		// Build detail mesh.
		int nverts = 0;
		if (!buildPolyDetail(ctx, poly, npoly,
							 sampleDist, sampleMaxError,
							 chf, hp, verts, nverts, tris,
							 edges, samples))
		{
			return false;
		}

		// Move detail verts to world space.
		for (int j = 0; j < nverts; ++j)
		{
			verts[j*3+0] += orig[0];
			verts[j*3+1] += orig[1] + chf.ch; // Is this offset necessary?
			verts[j*3+2] += orig[2];
		}
		// Offset poly too, will be used to flag checking.
		for (int j = 0; j < npoly; ++j)
		{
			poly[j*3+0] += orig[0];
			poly[j*3+1] += orig[1];
			poly[j*3+2] += orig[2];
		}
	
		// Store detail submesh.
		const int ntris = tris.size()/4;

		dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts;
		dmesh.meshes[i*4+1] = (unsigned int)nverts;
		dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris;
		dmesh.meshes[i*4+3] = (unsigned int)ntris;		
		
		// Store vertices, allocate more memory if necessary.
		if (dmesh.nverts+nverts > vcap)
		{
			while (dmesh.nverts+nverts > vcap)
				vcap += 256;
				
			float* newv = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM);
			if (!newv)
			{
				ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3);
				return false;
			}
			if (dmesh.nverts)
				memcpy(newv, dmesh.verts, sizeof(float)*3*dmesh.nverts);
			rcFree(dmesh.verts);
			dmesh.verts = newv;
		}
		for (int j = 0; j < nverts; ++j)
		{
			dmesh.verts[dmesh.nverts*3+0] = verts[j*3+0];
			dmesh.verts[dmesh.nverts*3+1] = verts[j*3+1];
			dmesh.verts[dmesh.nverts*3+2] = verts[j*3+2];
			dmesh.nverts++;
		}
		
		// Store triangles, allocate more memory if necessary.
		if (dmesh.ntris+ntris > tcap)
		{
			while (dmesh.ntris+ntris > tcap)
				tcap += 256;
			unsigned char* newt = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM);
			if (!newt)
			{
				ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4);
				return false;
			}
			if (dmesh.ntris)
				memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris);
			rcFree(dmesh.tris);
			dmesh.tris = newt;
		}
		for (int j = 0; j < ntris; ++j)
		{
			const int* t = &tris[j*4];
			dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0];
			dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1];
			dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2];
			dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly);
			dmesh.ntris++;
		}
	}
		
	ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL);

	return true;
}
コード例 #7
0
static int vector3_divide(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(stack.get_vector3(1) / stack.get_float(2));
	return 1;
}
コード例 #8
0
ファイル: nsLocation.cpp プロジェクト: lofter2011/Icefox
nsresult
nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
{
  *aLoadInfo = nsnull;

  nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
  NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE);

  nsresult rv;
  // Get JSContext from stack.
  nsCOMPtr<nsIJSContextStack>
    stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  JSContext *cx;

  NS_ENSURE_SUCCESS(GetContextFromStack(stack, &cx), NS_ERROR_FAILURE);

  nsCOMPtr<nsISupports> owner;
  nsCOMPtr<nsIURI> sourceURI;

  if (cx) {
    // No cx means that there's no JS running, or at least no JS that
    // was run through code that properly pushed a context onto the
    // context stack (as all code that runs JS off of web pages
    // does). We won't bother with security checks in this case, but
    // we need to create the loadinfo etc.

    // Get security manager.
    nsCOMPtr<nsIScriptSecurityManager>
      secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    // Check to see if URI is allowed.
    rv = secMan->CheckLoadURIFromScript(cx, aURI);
    NS_ENSURE_SUCCESS(rv, rv);

    // Now get the principal to use when loading the URI
    // First, get the principal and frame.
    JSStackFrame *fp;
    nsIPrincipal* principal = secMan->GetCxSubjectPrincipalAndFrame(cx, &fp);
    NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);

    nsCOMPtr<nsIURI> principalURI;
    principal->GetURI(getter_AddRefs(principalURI));

    // Make the load's referrer reflect changes to the document's URI caused by
    // push/replaceState, if possible.  First, get the document corresponding to
    // fp.  If the document's original URI (i.e. its URI before
    // push/replaceState) matches the principal's URI, use the document's
    // current URI as the referrer.  If they don't match, use the principal's
    // URI.

    nsCOMPtr<nsIDocument> frameDoc = GetFrameDocument(cx, fp);
    nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI;
    if (frameDoc) {
      docOriginalURI = frameDoc->GetOriginalURI();
      docCurrentURI = frameDoc->GetDocumentURI();
    }

    bool urisEqual = false;
    if (docOriginalURI && docCurrentURI && principalURI) {
      principalURI->Equals(docOriginalURI, &urisEqual);
    }

    if (urisEqual) {
      sourceURI = docCurrentURI;
    }
    else {
      sourceURI = principalURI;
    }

    owner = do_QueryInterface(principal);
  }

  // Create load info
  nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
  docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
  NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);

  loadInfo->SetOwner(owner);

  if (sourceURI) {
    loadInfo->SetReferrer(sourceURI);
  }

  loadInfo.swap(*aLoadInfo);

  return NS_OK;
}
コード例 #9
0
ファイル: RecastRegion.cpp プロジェクト: Jekls/PhantomCore
bool rcBuildRegions(rcCompactHeightfield& chf,
					int borderSize, int minRegionSize, int mergeRegionSize)
{
	rcTimeVal startTime = rcGetPerformanceTimer();
	
	const int w = chf.width;
	const int h = chf.height;

	if (!chf.regs)
	{
		chf.regs = new unsigned short[chf.spanCount];
		if (!chf.regs)
		{
			if (rcGetLog())
				rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'chf.reg' (%d).", chf.spanCount);
			return false;
		}
	}
	
	rcScopedDelete<unsigned short> tmp = new unsigned short[chf.spanCount*4];
	if (!tmp)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4);
		return false;
	}
	
	rcTimeVal regStartTime = rcGetPerformanceTimer();
	
	rcIntArray stack(1024);
	rcIntArray visited(1024);
	
	unsigned short* srcReg = tmp;
	unsigned short* srcDist = tmp+chf.spanCount;
	unsigned short* dstReg = tmp+chf.spanCount*2;
	unsigned short* dstDist = tmp+chf.spanCount*3;
	
	memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount);
	memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount);
	
	unsigned short regionId = 1;
	unsigned short level = (chf.maxDistance+1) & ~1;

	// TODO: Figure better formula, expandIters defines how much the 
	// watershed "overflows" and simplifies the regions. Tying it to
	// agent radius was usually good indication how greedy it could be.
//	const int expandIters = 4 + walkableRadius * 2;
	const int expandIters = 8;

	// Mark border regions.
	paintRectRegion(0, borderSize, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
	paintRectRegion(w-borderSize, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
	paintRectRegion(0, w, 0, borderSize, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
	paintRectRegion(0, w, h-borderSize, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;

	rcTimeVal expTime = 0;
	rcTimeVal floodTime = 0;
	
	while (level > 0)
	{
		level = level >= 2 ? level-2 : 0;
		
		rcTimeVal expStartTime = rcGetPerformanceTimer();
		
		// Expand current regions until no empty connected cells found.
		if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
		{
			rcSwap(srcReg, dstReg);
			rcSwap(srcDist, dstDist);
		}
		
		expTime += rcGetPerformanceTimer() - expStartTime;
		
		rcTimeVal floodStartTime = rcGetPerformanceTimer();
		
		// Mark new regions with IDs.
		for (int y = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
			{
				const rcCompactCell& c = chf.cells[x+y*w];
				for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
				{
					if (chf.dist[i] < level || srcReg[i] != 0 || chf.areas[i] == RC_NULL_AREA)
						continue;
					
					if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack))
						regionId++;
				}
			}
		}
		
		floodTime += rcGetPerformanceTimer() - floodStartTime;
		
	}
	
	// Expand current regions until no empty connected cells found.
	if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
	{
		rcSwap(srcReg, dstReg);
		rcSwap(srcDist, dstDist);
	}
	
	rcTimeVal regEndTime = rcGetPerformanceTimer();
	
	rcTimeVal filterStartTime = rcGetPerformanceTimer();
	
	// Filter out small regions.
	chf.maxRegions = regionId;
	if (!filterSmallRegions(minRegionSize, mergeRegionSize, chf.maxRegions, chf, srcReg))
		return false;
	
	rcTimeVal filterEndTime = rcGetPerformanceTimer();
		
	// Write the result out.
	memcpy(chf.regs, srcReg, sizeof(unsigned short)*chf.spanCount);
	
	rcTimeVal endTime = rcGetPerformanceTimer();
	
/*	if (rcGetLog())
	{
		rcGetLog()->log(RC_LOG_PROGRESS, "Build regions: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
		rcGetLog()->log(RC_LOG_PROGRESS, " - reg: %.3f ms", rcGetDeltaTimeUsec(regStartTime, regEndTime)/1000.0f);
		rcGetLog()->log(RC_LOG_PROGRESS, " - exp: %.3f ms", rcGetDeltaTimeUsec(0, expTime)/1000.0f);
		rcGetLog()->log(RC_LOG_PROGRESS, " - flood: %.3f ms", rcGetDeltaTimeUsec(0, floodTime)/1000.0f);
		rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.3f ms", rcGetDeltaTimeUsec(filterStartTime, filterEndTime)/1000.0f);
	}
*/
	if (rcGetBuildTimes())
	{
		rcGetBuildTimes()->buildRegions += rcGetDeltaTimeUsec(startTime, endTime);
		rcGetBuildTimes()->buildRegionsReg += rcGetDeltaTimeUsec(regStartTime, regEndTime);
		rcGetBuildTimes()->buildRegionsExp += rcGetDeltaTimeUsec(0, expTime);
		rcGetBuildTimes()->buildRegionsFlood += rcGetDeltaTimeUsec(0, floodTime);
		rcGetBuildTimes()->buildRegionsFilter += rcGetDeltaTimeUsec(filterStartTime, filterEndTime);
	}
		
	return true;
}
コード例 #10
0
dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc,
                                 const int minRegionArea, const int mergeRegionArea,
                                 dtTileCacheLayer& layer, dtTileCacheDistanceField dfield)
{
    dtAssert(alloc);

    const int w = (int)layer.header->width;
    const int h = (int)layer.header->height;
    const int size = w*h;

    dtFixedArray<unsigned short> buf(alloc, size*4);
    if (!buf)
    {
        return DT_FAILURE | DT_OUT_OF_MEMORY;
    }

    dtIntArray stack(1024);
    dtIntArray visited(1024);

    unsigned short* srcReg = buf;
    unsigned short* srcDist = buf+size;
    unsigned short* dstReg = buf+size*2;
    unsigned short* dstDist = buf+size*3;

    memset(srcReg, 0, sizeof(unsigned short)*size);
    memset(srcDist, 0, sizeof(unsigned short)*size);

    unsigned short regionId = 1;
    unsigned short level = (dfield.maxDist+1) & ~1;

    // TODO: Figure better formula, expandIters defines how much the
    // watershed "overflows" and simplifies the regions. Tying it to
    // agent radius was usually good indication how greedy it could be.
    //	const int expandIters = 4 + walkableRadius * 2;
    const int expandIters = 8;

    while (level > 0)
    {
        level = level >= 2 ? level-2 : 0;

        // Expand current regions until no empty connected cells found.
        if (expandRegions(expandIters, level, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
        {
            dtSwap(srcReg, dstReg);
            dtSwap(srcDist, dstDist);
        }

        // Mark new regions with IDs.
        for (int y = 0; y < h; ++y)
        {
            for (int x = 0; x < w; ++x)
            {
                const int i=x+y*w;
                if (dfield.data[i] < level || srcReg[i] != 0 || layer.areas[i] == DT_TILECACHE_NULL_AREA)
                    continue;
                if (floodRegion(x, y, i, level, regionId, layer, dfield, srcReg, srcDist, stack))
                    regionId++;
            }
        }
    }

    // Expand current regions until no empty connected cells found.
    if (expandRegions(expandIters*8, 0, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
    {
        dtSwap(srcReg, dstReg);
        dtSwap(srcDist, dstDist);
    }

    dtStatus status = filterSmallRegions(alloc, layer, minRegionArea, mergeRegionArea, regionId, srcReg);
    if (dtStatusFailed(status))
    {
        return status;
    }

    // Write the result out.
    memcpy(layer.regs, srcReg, sizeof(unsigned short)*size);
    layer.regCount = regionId;

    return DT_SUCCESS;
}
コード例 #11
0
ファイル: yssa_codegen.cpp プロジェクト: edmundmk/ylang
size_t ygen_emit::opgen( ygen_program* p, size_t index )
{
    yssa_function* function = p->ssafunc;

    yssa_opinst* op = function->ops.at( index );
    switch ( op->opcode )
    {
    case YL_NOP:
    {
        p->ops.emplace_back( YL_NOP, 0, 0, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_MOV:
    {
        assert( op->result_count == 1 );
        assert( op->operand_count == 1 );
        if ( op->r != yl_opinst::NOVAL && op->r != op->operand[ 0 ]->r )
        {
            unsigned a = op->operand[ 0 ]->r;
            assert( a != yl_opinst::NOVAL );
            p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_NULL:
    case YL_NEG:
    case YL_BITNOT:
    case YL_MUL:
    case YL_DIV:
    case YL_MOD:
    case YL_INTDIV:
    case YL_ADD:
    case YL_SUB:
    case YL_LSL:
    case YL_LSR:
    case YL_ASR:
    case YL_BITAND:
    case YL_BITXOR:
    case YL_BITOR:
    case YL_CONCAT:
    case YL_EQ:
    case YL_NE:
    case YL_LT:
    case YL_GT:
    case YL_LE:
    case YL_GE:
    case YL_LNOT:
    case YL_LXOR:
    case YL_SUPER:
    case YL_INKEY:
    case YL_INDEX:
    case YL_RESPONDS:
    case YL_IS:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned a = operand( op, 0 );
            unsigned b = operand( op, 1 );
            p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, b );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_BOOL:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned a = op->boolean ? 1 : 0;
            p->ops.emplace_back( YL_BOOL, op->r, a, 0 );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_NUMBER:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned c = (unsigned)p->numvals.at( op->number );
            p->ops.emplace_back( YL_NUMBER, op->r, c );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_STRING:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            symkey k( op->string->string, op->string->length );
            unsigned c = (unsigned)p->strvals.at( k );
            p->ops.emplace_back( YL_STRING, op->r, c );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
     
    case YL_GLOBAL:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned b = (unsigned)p->strvals.at( op->key );
            p->ops.emplace_back( YL_GLOBAL, op->r, 0, b );
            p->slocs.push_back( op->sloc );
            p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_SETGLOBAL:
    {
        assert( op->result_count == 0 );
        unsigned r = operand( op, 0 );
        unsigned b = (unsigned)p->strvals.at( op->key );
        p->ops.emplace_back( YL_SETGLOBAL, r, 0, b );
        p->slocs.push_back( op->sloc );
        p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) );
        p->slocs.push_back( op->sloc );
        return 1;
    }

    case YL_FUNCTION:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned c = (unsigned)p->funvals.at( op->function );
            p->ops.emplace_back( YL_FUNCTION, op->r, c );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
    
        size_t n;
        for ( n = 1; index + n < function->ops.size(); ++n )
        {
            yssa_opinst* up = function->ops.at( index + n );
            if ( up->opcode == YL_UPLOCAL )
            {
                if ( op->r != yl_opinst::NOVAL )
                {
                    unsigned b = operand( up, 0 );
                    p->ops.emplace_back( YL_UPLOCAL, up->r, up->a, b );
                    p->slocs.push_back( op->sloc );
                    p->localupcount = std::max( p->localupcount, (size_t)up->a + 1 );
                }
            }
            else if ( up->opcode == YL_UPUPVAL )
            {
                if ( op->r != yl_opinst::NOVAL )
                {
                    p->ops.emplace_back( YL_UPUPVAL, up->r, up->a, 0 );
                    p->slocs.push_back( op->sloc );
                }
            }
            else
            {
                break;
            }
        }
        return n;
    }
    
    case YL_VARARG:
    case YL_CALL:
    case YL_YCALL:
    case YL_YIELD:
    case YL_RETURN:
    case YL_NEXT:
    case YL_EXTEND:
    case YL_UNPACK:
    {
        assert( op->is_call() );
    
        // These ops can either produce or consume multiple values.  We must
        // treat chains of multivals as a single operation on top of stack.
        yssa_opinst* multival = op;
        yssa_opinst* firstop = op;
        yssa_opinst* finalop = op;
        size_t ilast = index + 1;
        for ( ; ilast < function->ops.size(); ++ilast )
        {
            yssa_opinst* op = function->ops.at( ilast );

            if ( op->opcode == YSSA_IMPLICIT )
            {
                continue;
            }
            
            if ( op->is_call() && op->multival == multival )
            {
                // Follow the multival chain.
                multival = op;
                finalop = op;
                continue;
            }

            // Multival results must be consumed by the next instruction.
            assert( ! op->has_multival() || ! op->multival );
            break;
        }
    
        
        // Get all operands into the correct registers.
        ygen_movgraph arguments;

        for ( size_t iop = index; iop < ilast; ++iop )
        {
            op = function->ops.at( iop );
            if ( op->opcode == YSSA_IMPLICIT )
            {
                continue;
            }
            
            // First argument of UNPACK and EXTEND can be any register.
            unsigned first = 0;
            if ( op->opcode == YL_UNPACK || op->opcode == YL_EXTEND )
            {
                unsigned a = operand( op, first++ );
                if ( a >= multival->stacktop )
                {
                    arguments.move( op->stacktop, a );
                    op->operand[ 0 ]->r = op->stacktop;
                }
            }
            
            // Move remaining operands.
            for ( unsigned iarg = first; iarg < op->operand_count; ++iarg )
            {
                unsigned a = operand( op, iarg );
                unsigned r = op->stacktop + iarg - first;
                arguments.move( r, a );
            }
        }
        
        arguments.emit( p, firstop->sloc );
        

        // Emit instructions.
        for ( size_t iop = index; iop < ilast; ++iop )
        {
            op = function->ops.at( iop );
            if ( op->opcode == YSSA_IMPLICIT )
            {
                continue;
            }
            
            assert( op->is_call() );
            assert( op->stacktop != yl_opinst::NOVAL );
        
            switch ( op->opcode )
            {
            case YL_VARARG:
            case YL_CALL:
            case YL_YCALL:
            case YL_YIELD:
            case YL_RETURN:
            {
                unsigned a = op->multival ? yl_opinst::MARK : op->operand_count;
                unsigned b = op->result_count;
                p->ops.emplace_back( (yl_opcode)op->opcode, op->stacktop, a, b );
                p->slocs.push_back( op->sloc );
                stack( p, op->stacktop, op->result_count );
                break;
            }
            
            case YL_NEXT:
            {
                p->ops.emplace_back( YL_NEXT, op->stacktop, op->a, op->result_count );
                p->slocs.push_back( op->sloc );
                stack( p, op->stacktop, op->result_count );
                break;
            }
            
            case YL_EXTEND:
            {
                unsigned a = op->multival ? yl_opinst::MARK : op->operand_count;
                unsigned b = operand( op, 0 );
                p->ops.emplace_back( YL_EXTEND, op->stacktop, a, b );
                p->slocs.push_back( op->sloc );
                break;
            }
            
            case YL_UNPACK:
            {
                unsigned a = operand( op, 0 );
                p->ops.emplace_back( YL_UNPACK, op->stacktop, a, op->result_count );
                p->slocs.push_back( op->sloc );
                stack( p, op->stacktop, op->result_count );
                break;
            }
            
            default:
                assert( ! "unexpected multival operation" );
                break;
            }
        }


        // Results of final op.
        op = finalop;
        assert( op->is_call() );
        
        // RETURN and EXTEND don't return any results.
        if ( op->opcode == YL_RETURN || op->opcode == YL_EXTEND )
        {
            assert( op->result_count == 0 );
            return ilast - index;
        }
        
        // Move all results into the correct registers.
        ygen_movgraph results;
        
        if ( op->r != yl_opinst::NOVAL )
        {
            results.move( op->r, op->stacktop );
        }
        
        for ( ; ilast < function->ops.size(); ++ilast )
        {
            yssa_opinst* sel = function->ops.at( ilast );
            if ( sel->opcode == YSSA_IMPLICIT )
            {
                continue;
            }

            if ( sel->opcode == YSSA_SELECT )
            {
                assert( sel->operand_count == 1 );
                assert( sel->operand[ 0 ] == op );
                if ( sel->r != yl_opinst::NOVAL )
                {
                    results.move( sel->r, op->stacktop + sel->select );
                }
                continue;
            }

            break;
        }
    
        results.emit( p, finalop->sloc );
        return ilast - index;
    }
     
    case YL_ITER:
    case YL_ITERKEY:
    {
        unsigned a = operand( op, 0 );
        p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 );
        p->slocs.push_back( op->sloc );
        p->itercount = std::max( p->itercount, (size_t)op->r + 1 );
        return 1;
    }
    
    case YL_NEXT1:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            p->ops.emplace_back( YL_NEXT1, op->r, op->a );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_NEXT2:
    {
        // Find selects.
        unsigned r = yl_opinst::NOVAL;
        unsigned b = yl_opinst::NOVAL;
        
        size_t n;
        for ( n = 1; index + n < function->ops.size(); ++n )
        {
            yssa_opinst* sel = function->ops.at( index + n );
            if ( sel->opcode == YSSA_SELECT )
            {
                assert( sel->operand_count == 1 );
                assert( sel->operand[ 0 ] == op );
                
                if ( sel->select == 0 )
                {
                    r = sel->r;
                }
                else if ( sel->select == 1 )
                {
                    b = sel->r;
                }
                else
                {
                    assert( ! "invalid select index" );
                }
            }
            else
            {
                break;
            }
        }
        
        assert( r != yl_opinst::NOVAL );
        assert( b != yl_opinst::NOVAL );
        p->ops.emplace_back( YL_NEXT2, r, op->a, b );
        p->slocs.push_back( op->sloc );
        p->stackcount = std::max( p->stackcount, (size_t)r + 1 );
        p->stackcount = std::max( p->stackcount, (size_t)b + 1 );
        return n;
    }
    
    case YL_GETUP:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            p->ops.emplace_back( YL_GETUP, op->r, op->a, 0 );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_SETUP:
    {
        p->ops.emplace_back( YL_SETUP, operand( op, 0 ), op->a, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_OBJECT:
    {
        assert( op->result_count == 1 );
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned a = op->operand_count ? operand( op, 0 ) : yl_opinst::NOVAL;
            p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
 
    case YL_CLOSE:
    {
        p->ops.emplace_back( YL_CLOSE, 0, op->a, op->b );
        p->slocs.push_back( op->sloc );
        return 1;
    }
 
    case YL_ARRAY:
    case YL_TABLE:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            p->ops.emplace_back( (yl_opcode)op->opcode, op->r, op->c );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
     
    case YL_KEY:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            unsigned b = (unsigned)p->strvals.at( op->key );
            p->ops.emplace_back( YL_KEY, op->r, operand( op, 0 ), b );
            p->slocs.push_back( op->sloc );
            p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_SETKEY:
    {
        unsigned r = operand( op, 0 );
        unsigned a = operand( op, 1 );
        unsigned b = (unsigned)p->strvals.at( op->key );
        p->ops.emplace_back( YL_SETKEY, r, a, b );
        p->slocs.push_back( op->sloc );
        p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_SETINKEY:
    case YL_SETINDEX:
    {
        assert( op->operand_count == 3 );
        unsigned r = operand( op, 0 );
        unsigned a = operand( op, 1 );
        unsigned b = operand( op, 2 );
        p->ops.emplace_back( (yl_opcode)op->opcode, r, a, b );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_DELKEY:
    {
        unsigned a = operand( op, 0 );
        unsigned b = (unsigned)p->strvals.at( op->key );
        p->ops.emplace_back( YL_DELKEY, 0, a, b );
        p->slocs.push_back( op->sloc );
        return 1;
    }

    case YL_DELINKEY:
    {
        unsigned a = operand( op, 0 );
        unsigned b = operand( op, 1 );
        p->ops.emplace_back( YL_DELINKEY, 0, a, b );
        p->slocs.push_back( op->sloc );
        return 1;
    }
     
    case YL_APPEND:
    {
        unsigned a = operand( op, 0 );
        unsigned r = operand( op, 1 );
        p->ops.emplace_back( YL_APPEND, r, a, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
     
    case YL_THROW:
    {
        p->ops.emplace_back( YL_THROW, operand( op, 0 ), 0, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_EXCEPT:
    {
        if ( op->r != yl_opinst::NOVAL )
        {
            p->ops.emplace_back( YL_EXCEPT, op->r, 0, 0 );
            p->slocs.push_back( op->sloc );
            p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 );
        }
        return 1;
    }
    
    case YL_HANDLE:
    {
        p->ops.emplace_back( YL_HANDLE, 0, 0, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
    
    case YL_UNWIND:
    {
        p->ops.emplace_back( YL_UNWIND, 0, 0, 0 );
        p->slocs.push_back( op->sloc );
        return 1;
    }
 
    case YSSA_PARAM:
    {
        // Get all parameters into the correct registers.
        ygen_movgraph params;
        
        size_t n;
        for ( n = 0; index + n < function->ops.size(); ++n )
        {
            yssa_opinst* param = function->ops.at( index + n );
            if ( param->opcode == YSSA_PARAM )
            {
                unsigned a = param->select + 1;
                p->stackcount = std::max( p->stackcount, (size_t)a + 1 );
                if ( param->r != yl_opinst::NOVAL )
                {
                    params.move( param->r, a );
                }
            }
            else
            {
                break;
            }
        }
        
        params.emit( p, op->sloc );
        return n;
    }

    case YSSA_IMPLICIT:
    case YSSA_ITEREACH:
    case YSSA_PHI:
    case YSSA_VAR:
    {
        // Ignore these ops.
        return 1;
    }

    case YL_SWP:
    case YL_JMP:
    case YL_JMPT:
    case YL_JMPF:
    case YL_JMPV:
    case YL_JMPN:
    case YL_UPLOCAL:
    case YL_UPUPVAL:
    case YSSA_SELECT:
    case YSSA_REF:
    default:
    {
        assert( ! "unexpected SSA op" );
        return 1;
    }

    
    }
}
コード例 #12
0
static dtStatus filterSmallRegions(dtTileCacheAlloc* alloc, dtTileCacheLayer& layer, int minRegionArea, int mergeRegionSize,
                                   unsigned short& maxRegionId, unsigned short* srcReg)
{
    const int w = (int)layer.header->width;
    const int h = (int)layer.header->height;

    const int nreg = maxRegionId+1;
    dtFixedArray<dtLayerRegion> regions(alloc, nreg);
    if (!regions)
    {
        return DT_FAILURE | DT_OUT_OF_MEMORY;
    }

    // Construct regions
    regions.set(0);
    for (int i = 0; i < nreg; ++i)
        regions[i] = dtLayerRegion((unsigned short)i);

    // Find edge of a region and find connections around the contour.
    for (int y = 0; y < h; ++y)
    {
        const bool borderY = (y == 0) || (y == (h - 1));
        for (int x = 0; x < w; ++x)
        {
            const int i = x+y*w;
            unsigned short r = srcReg[i];

            if (r == DT_TILECACHE_NULL_AREA || r >= nreg)
                continue;

            dtLayerRegion& reg = regions[r];
            reg.cellCount++;
            reg.border |= borderY || (x == 0) || (x == (w - 1));

            // Have found contour
            if (reg.connections.size() > 0)
                continue;

            reg.areaType = layer.areas[i];

            // Check if this cell is next to a border.
            int ndir = -1;
            for (int dir = 0; dir < 4; ++dir)
            {
                if (isSolidEdge(layer, srcReg, x, y, i, dir))
                {
                    ndir = dir;
                    break;
                }
            }

            if (ndir != -1)
            {
                // The cell is at border.
                // Walk around the contour to find all the neighbours.
                walkContour(x, y, i, ndir, layer, srcReg, reg.connections);
            }
        }
    }

    // Remove too small regions.
    dtIntArray stack(32);
    dtIntArray trace(32);
    for (int i = 0; i < nreg; ++i)
    {
        dtLayerRegion& reg = regions[i];
        if (reg.id == 0)
            continue;
        if (reg.cellCount == 0)
            continue;
        if (reg.visited)
            continue;

        // Count the total size of all the connected regions.
        // Also keep track of the regions connects to a tile border.
        bool connectsToBorder = false;
        int cellCount = 0;
        stack.resize(0);
        trace.resize(0);

        reg.visited = true;
        stack.push(i);

        while (stack.size())
        {
            // Pop
            int ri = stack.pop();

            dtLayerRegion& creg = regions[ri];

            connectsToBorder |= creg.border;
            cellCount += creg.cellCount;
            trace.push(ri);

            for (int j = 0; j < creg.connections.size(); ++j)
            {
                dtLayerRegion& neireg = regions[creg.connections[j]];
                if (neireg.visited)
                    continue;
                if (neireg.id == 0)
                    continue;
                // Visit
                stack.push(neireg.id);
                neireg.visited = true;
            }
        }

        // If the accumulated regions size is too small, remove it.
        // Do not remove areas which connect to tile borders
        // as their size cannot be estimated correctly and removing them
        // can potentially remove necessary areas.
        if (cellCount < minRegionArea && !connectsToBorder)
        {
            // Kill all visited regions.
            for (int j = 0; j < trace.size(); ++j)
            {
                regions[trace[j]].cellCount = 0;
                regions[trace[j]].id = 0;
            }
        }
    }

    // Merge too small regions to neighbour regions.
    int mergeCount = 0 ;
    do
    {
        mergeCount = 0;
        for (int i = 0; i < nreg; ++i)
        {
            dtLayerRegion& reg = regions[i];
            if (reg.id == 0)
                continue;
            if (reg.cellCount == 0)
                continue;

            // Check to see if the region should be merged.
            if (reg.cellCount > mergeRegionSize && reg.border)
                continue;

            // Small region with more than 1 connection.
            // Or region which is not connected to a border at all.
            // Find smallest neighbour region that connects to this one.
            int smallest = 0xfffffff;
            unsigned short mergeId = reg.id;
            for (int j = 0; j < reg.connections.size(); ++j)
            {
                dtLayerRegion& mreg = regions[reg.connections[j]];
                if (mreg.id == 0) continue;
                if (mreg.cellCount < smallest &&
                        canMergeWithRegion(reg, mreg) &&
                        canMergeWithRegion(mreg, reg))
                {
                    smallest = mreg.cellCount;
                    mergeId = mreg.id;
                }
            }
            // Found new id.
            if (mergeId != reg.id)
            {
                unsigned short oldId = reg.id;
                dtLayerRegion& target = regions[mergeId];

                // Merge neighbours.
                if (mergeRegions(target, reg))
                {
                    // Fixup regions pointing to current region.
                    for (int j = 0; j < nreg; ++j)
                    {
                        if (regions[j].id == 0) continue;
                        // If another region was already merged into current region
                        // change the nid of the previous region too.
                        if (regions[j].id == oldId)
                            regions[j].id = mergeId;
                        // Replace the current region with the new one if the
                        // current regions is neighbour.
                        replaceNeighbour(regions[j], oldId, mergeId);
                    }
                    mergeCount++;
                }
            }
        }
    }
    while (mergeCount > 0);

    // Compress region Ids.
    for (int i = 0; i < nreg; ++i)
    {
        regions[i].remap = false;
        if (regions[i].id == DT_TILECACHE_NULL_AREA) continue;       // Skip nil regions.
        regions[i].remap = true;
    }

    unsigned short regIdGen = 0;
    for (int i = 0; i < nreg; ++i)
    {
        if (!regions[i].remap)
            continue;
        unsigned short oldId = regions[i].id;
        unsigned short newId = ++regIdGen;
        for (int j = i; j < nreg; ++j)
        {
            if (regions[j].id == oldId)
            {
                regions[j].id = newId;
                regions[j].remap = false;
            }
        }
    }
    maxRegionId = regIdGen;

    // Remap regions.
    for (int i = w*h-1; i >= 0; i--)
    {
        srcReg[i] = regions[srcReg[i]].id;
    }

    for (int i = 0; i < nreg; ++i)
        regions[i].~dtLayerRegion();

    return DT_SUCCESS;
}
コード例 #13
0
static void MergeAndCompressRegions(dtTileCacheAlloc* alloc, dtTileCacheLayer& layer, dtLayerMonotoneRegion* regs, int nregs, const int minRegionArea, const int mergeRegionArea)
{
    for (int i = 0; i < nregs; ++i)
        regs[i].regId = (unsigned short)(i + 1);

    // Remove too small regions.
    if (minRegionArea > 0)
    {
        dtIntArray stack(32);
        dtIntArray trace(32);
        for (int i = 0; i < nregs; ++i)
        {
            dtLayerMonotoneRegion& reg = regs[i];
            if (reg.visited || reg.area == 0)
                continue;

            // Count the total size of all the connected regions.
            // Also keep track of the regions connects to a tile border.
            bool connectsToBorder = false;
            int cellCount = 0;
            stack.resize(0);
            trace.resize(0);

            reg.visited = true;
            stack.push(i);

            while (stack.size())
            {
                // Pop
                int ri = stack.pop();

                dtLayerMonotoneRegion& creg = regs[ri];

                connectsToBorder |= creg.border;
                cellCount += creg.area;
                trace.push(ri);

                for (int j = 0; j < creg.neis.size(); ++j)
                {
                    dtLayerMonotoneRegion& neireg = regs[creg.neis[j]];
                    if (neireg.visited)
                        continue;
                    if (neireg.regId == 0)
                        continue;
                    // Visit
                    stack.push(neireg.regId - 1);
                    neireg.visited = true;
                }
            }

            // If the accumulated regions size is too small, remove it.
            // Do not remove areas which connect to tile borders
            // as their size cannot be estimated correctly and removing them
            // can potentially remove necessary areas.
            if (cellCount < minRegionArea && !connectsToBorder)
            {
                // Kill all visited regions.
                for (int j = 0; j < trace.size(); ++j)
                {
                    regs[trace[j]].area = 0;
                    regs[trace[j]].regId = 0;
                }
            }
        }
    }

    for (int i = 0; i < nregs; ++i)
    {
        dtLayerMonotoneRegion& reg = regs[i];
        if (reg.regId == 0)
            continue;
        // don't use mergeRegionArea, it doesn't work well with monotone partitioning
        // (results in even more long thin polys)

        int merge = -1;
        int mergea = 0;
        for (int j = 0; j < reg.neis.size(); ++j)
        {
            const unsigned short nei = (unsigned short)reg.neis[j];
            dtLayerMonotoneRegion& regn = regs[nei];
            if (reg.regId == regn.regId)
                continue;
            if (reg.areaId != regn.areaId || reg.chunkId != regn.chunkId)
                continue;
            if (regn.area > mergea)
            {
                if (canMerge(reg.regId, regn.regId, regs, nregs))
                {
                    mergea = regn.area;
                    merge = (int)nei;
                }
            }
        }
        if (merge != -1)
        {
            const unsigned short oldId = reg.regId;
            const unsigned short newId = regs[merge].regId;
            for (int j = 0; j < nregs; ++j)
                if (regs[j].regId == oldId)
                    regs[j].regId = newId;
        }
    }

    unsigned short regId = 0;
    if (nregs < 256)
    {
        // Compact ids.
        unsigned short remap[256];
        memset(remap, 0, sizeof(unsigned short)*256);
        // Find number of unique regions.
        for (int i = 0; i < nregs; ++i)
            remap[regs[i].regId] = 1;
        // skip region id 0, it's used for skipping minRegionArea
        remap[0] = 0;
        for (int i = 1; i < 256; ++i)
            if (remap[i])
                remap[i] = ++regId;
        // Remap ids.
        for (int i = 0; i < nregs; ++i)
            regs[i].regId = remap[regs[i].regId];
    }
    else
    {
        for (int i = 0; i < nregs; ++i)
            regs[i].remap = true;

        for (int i = 0; i < nregs; ++i)
        {
            // skip region id 0, it's used for skipping minRegionArea
            if (!regs[i].remap || regs[i].regId == 0)
                continue;
            unsigned short oldId = regs[i].regId;
            unsigned short newId = ++regId;
            for (int j = i; j < nregs; ++j)
            {
                if (regs[j].regId == oldId)
                {
                    regs[j].regId = newId;
                    regs[j].remap = false;
                }
            }
        }
    }

    layer.regCount = regId;

    const int maxi = (int)layer.header->width * (int)layer.header->height;
    for (int i = 0; i < maxi; ++i)
    {
        if (layer.regs[i] != 0xffff)
            layer.regs[i] = regs[layer.regs[i]].regId;
    }

    alloc->free(regs);
}
コード例 #14
0
ファイル: JavaVM.cpp プロジェクト: BRomano/e-jvm
boost::shared_ptr<StackFrame> JavaVM::createStack()
{
	boost::shared_ptr<StackFrame> stack(new StackFrame());
	return stack;
}
コード例 #15
0
ファイル: BIH.cpp プロジェクト: LudoSapiens/Dev
//------------------------------------------------------------------------------
//!
void
BIH::create(
   const Vector<AABBoxf*>& bboxes,
   const Vector<Vec3f>&    centers,
   Vector<uint>*           ids,
   uint                    leafSize,
   uint                    maxDepth
)
{
   CHECK( bboxes.size() == centers.size() );

   DBG_BLOCK( os_bih, "Start computing BIH..." );
   DBG( Timer timer );

   // Initialization.
   DBG_MSG( os_bih, "# of elements: " << bboxes.size() << " " << centers.size() << "\n" );
   // 1. Init maximum recursion level.
   if( maxDepth == 0 )
   {
      maxDepth = (int)CGM::log2( float(centers.size()) ) * 2 + 1;
   }
   _maxDepth = CGM::min( maxDepth, (uint)100 );

   // 2. Init ids.
   if( ids == 0 )
   {
      _ids.resize( centers.size() );
      for( uint i = 0; i < _ids.size(); ++i )
      {
         _ids[i] = i;
      }
   }
   else
   {
      _ids.swap( *ids );
   }
   
   Vector<uint>  remap( centers.size() );
   for( uint i = 0; i < remap.size(); ++i )
   {
      remap[i] = i;
   }

   // 3. Init nodes and root.
   //_nodes.reserve();
   _nodes.resize(1);

   // 4. Compute bounding box.
   AABBoxf nodeBox  = AABBoxf::empty();
   for( uint i = 0; i < bboxes.size(); ++i )
   {
      nodeBox |= *bboxes[i];
   }
   AABBoxf splitBox = nodeBox;

   // 5. Stack.
   Vector<BuildStackNode> stack( maxDepth );
   uint stackID = 0;

   uint maxPrim = 0;
   uint maxD = 0;

   // Construct BIH.
   uint begin = 0;
   uint end   = uint(_ids.size());
   uint depth = 1;
   uint node  = 0;
   while( 1 )
   {
      // Do we have a root node?
      if( (end - begin <= leafSize) || depth >= maxDepth )
      {
         // Root node.
         _nodes[node]._index = (begin << 3) + 3;
         _nodes[node]._numElements = end-begin;

         maxPrim = CGM::max( maxPrim, end-begin );
         maxD = CGM::max( maxD, depth );

         // Are we done?
         if( stackID == 0 )
         {
            break;
         }
         stack[--stackID].get( node, begin, end, depth, nodeBox, splitBox );
      }
      else
      {
         // Compute split plane and axis.
         uint axis        = splitBox.longestSide();
         float splitPlane = splitBox.center( axis );

         // Partition primitives.
         AABBoxf leftNodeBox  = AABBoxf::empty();
         AABBoxf rightNodeBox = AABBoxf::empty();
         uint pivot = begin;
         for( uint i = begin; i < end; ++i )
         {
            if( centers[remap[i]](axis) < splitPlane )
            {
               leftNodeBox |= (*bboxes[remap[i]]);
               CGM::swap( remap[i], remap[pivot] );
               CGM::swap( _ids[i], _ids[pivot++] );
            }
            else
            {
               rightNodeBox |= (*bboxes[remap[i]]);
            }
         }

         // Construct node.
         ++depth;
         // No left node.
         if( pivot == begin )
         {
            uint childNode = uint(_nodes.size());

            // Current node.
            _nodes[node]._index    = (childNode << 3) + 4 + axis;
            _nodes[node]._plane[0] = rightNodeBox.min( axis );
            _nodes[node]._plane[1] = rightNodeBox.max( axis );

            // Create nodes.
            _nodes.pushBack( Node() );

            // Child node.
            node     = childNode;
            nodeBox  = rightNodeBox;
            splitBox.slab( axis )(0) = CGM::max( splitPlane, rightNodeBox.min( axis ) );
         }
         // No right node.
         else if( pivot == end )
         {
            uint childNode = uint(_nodes.size());

            // Current node.
            _nodes[node]._index    = (childNode << 3) + 4 + axis;
            _nodes[node]._plane[0] = leftNodeBox.min( axis );
            _nodes[node]._plane[1] = leftNodeBox.max( axis );

            // Create nodes.
            _nodes.pushBack( Node() );

            // Child node.
            node     = childNode;
            nodeBox  = leftNodeBox;
            splitBox.slab( axis )(1) = CGM::min( splitPlane, leftNodeBox.max( axis ) );
         }
         // Left and right node.
         else
         {
            uint leftNode = uint(_nodes.size());

            // Current node.
            _nodes[node]._index    = (leftNode << 3) + axis;
            _nodes[node]._plane[0] = leftNodeBox.max( axis );
            _nodes[node]._plane[1] = rightNodeBox.min( axis );

            // Create nodes.
            _nodes.pushBack( Node() );
            _nodes.pushBack( Node() );

            // Right node.
            AABBoxf rsplitBox( splitBox );
            rsplitBox.slab( axis )(0) = splitPlane;
            stack[stackID++].set( leftNode+1, pivot, end, depth, rightNodeBox, rsplitBox );

            // Left node.
            node     = leftNode;
            end      = pivot;
            nodeBox  = leftNodeBox;
            splitBox.slab( axis )(1) = splitPlane;
         }
      }
   }

   DBG( double time = timer.elapsed() );
   DBG_MSG( os_bih, "...finish in " << time << " sec." );
   DBG_MSG( os_bih, "# of nodes: " << _nodes.size() );
   DBG_MSG( os_bih, "# of indices: " << _ids.size() );
   DBG_MSG( os_bih, "max primitives in a leaf: " << maxPrim );
   DBG_MSG( os_bih, "max depth: " << maxD << " " << maxDepth );
}
コード例 #16
0
void LaplacianFilter::parse(vector<string> args) {
  assert(args.size() == 0, "-laplacianpyramid does not take arguments.\n");
  push(apply(stack(0), 0.f, 0.f, 0.f));
}
コード例 #17
0
ファイル: BIH.cpp プロジェクト: LudoSapiens/Dev
//------------------------------------------------------------------------------
//!
bool
BIH::trace( const Rayf& ray, Hit& hit, IntersectFunc intersect, void* data ) const
{
   DBG_BLOCK( os_bih_trace, "BIH::trace(" << ray.origin() << ray.direction() << " hit: t=" << hit._t << " id=" << hit._id << ")" );
   if( _nodes.empty() )
   {
      return false;
   }

   Vec3f invDir = ray.direction().getInversed(); 

   // Compute traversal order.
   uint order[3];
   order[0] = invDir(0) >= 0.0f ? 0 : 1;
   order[1] = invDir(1) >= 0.0f ? 0 : 1;
   order[2] = invDir(2) >= 0.0f ? 0 : 1;

   float tmin  = 0.0f;
   float tmax  = hit._t;
   bool impact = false;


   // Traverse tree.
   Vector<TraversalStackNode> stack( _maxDepth );
   uint stackID = 0;
   const Node* node = &_nodes[0];

   while( 1 )
   {
      DBG_MSG( os_bih_trace, "Visiting " << *node );
      if( node->isInteriorNode() )
      {
         uint axis     = node->axis();
         float tplane0 = ( node->_plane[order[axis]] - ray.origin()(axis)) * invDir(axis);
         float tplane1 = ( node->_plane[1-order[axis]] - ray.origin()(axis)) * invDir(axis);

         // Clip node.
         if( node->isClipNode() )
         {
            // FIXME: we could probably do better (not traversing this node).
            node = &_nodes[node->index()];
            tmin = CGM::max( tmin, tplane0 );
            tmax = CGM::min( tmax, tplane1 );
            continue;
         }

         bool traverse0 = tmin < tplane0;
         bool traverse1 = tmax > tplane1;

         if( traverse0 )
         {
            if( traverse1 )
            {
               stack[stackID++].set(
                  &_nodes[node->index() + 1-order[axis]],
                  CGM::max( tmin, tplane1 ),
                  tmax
               );
            }
            node = &_nodes[node->index() + order[axis]];
            tmax = CGM::min( tmax, tplane0 );
         }
         else
         {
            if( traverse1 )
            {
               node = &_nodes[node->index() + 1-order[axis]];
               tmin = CGM::max( tmin, tplane1 );
            }
            else
            {
               // Unstack.
               do
               {
                  if( stackID == 0 )
                  {
                     return impact;
                  }
                  stack[--stackID].get( node, tmin, tmax );
                  tmax = CGM::min( tmax, hit._t );
               } while( tmin > tmax );
            }
         }

      }
      else
      {
         // We are in a leaf node.
         // Intersects all primitives in it.
         uint numElems = node->_numElements;
         uint id       = node->index();
         for( uint i = 0; i < numElems; ++i, ++id )
         {
            if( intersect( ray, _ids[id], hit._t, data ) )
            {
               impact  = true;
               hit._id = _ids[id];
            }
         }

         // Unstack.
         do
         {
            if( stackID == 0 )
            {
               return impact;
            }
            stack[--stackID].get( node, tmin, tmax );
            tmax = CGM::min( tmax, hit._t );
         } while( tmin > tmax );
      }
   }
}
コード例 #18
0
ファイル: ScriptSettings.cpp プロジェクト: Pike/gecko-dev
void
AutoJSAPI::ReportException()
{
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal) {
    if (mIsMainThread) {
      errorGlobal = xpc::PrivilegedJunkScope();
    } else {
      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
    }
  }
  JSAutoCompartment ac(cx(), errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) &&
      jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
    if (mIsMainThread) {
      RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();

      RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      if (!win) {
        // We run addons in a separate privileged compartment, but they still
        // expect to trigger the onerror handler of their associated DOM Window.
        win = xpc::AddonWindowOrNull(errorGlobal);
      }
      nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
      xpcReport->Init(jsReport.report(), jsReport.message(),
                      nsContentUtils::IsCallerChrome(),
                      inner ? inner->WindowID() : 0);
      if (inner && jsReport.report()->errorNumber != JSMSG_OUT_OF_MEMORY) {
        DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn);
      } else {
        JS::Rooted<JSObject*> stack(cx(),
          xpc::FindExceptionStackForConsoleReport(inner, exn));
        xpcReport->LogToConsoleWithStack(stack);
      }
    } else {
      // On a worker, we just use the worker error reporting mechanism and don't
      // bother with xpc::ErrorReport.  This will ensure that all the right
      // events (which are a lot more complicated than in the window case) get
      // fired.
      workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(worker);
      MOZ_ASSERT(worker->GetJSContext() == cx());
      // Before invoking ReportError, put the exception back on the context,
      // because it may want to put it in its error events and has no other way
      // to get hold of it.  After we invoke ReportError, clear the exception on
      // cx(), just in case ReportError didn't.
      JS_SetPendingException(cx(), exn);
      worker->ReportError(cx(), jsReport.message(), jsReport.report());
      ClearException();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
    ClearException();
  }
}
コード例 #19
0
ファイル: test_SA_00001.cpp プロジェクト: optimad/bitpit
// -------------------------------------------------------------------------- //
void Test000(
    void
) {

// ========================================================================== //
// void Test000(                                                              //
//     void)                                                                  //
//                                                                            //
// LIFO stack demo.                                                           //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - none                                                                     //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - none                                                                     //
// ========================================================================== //

// ========================================================================== //
// VARIABLES DECLARATION                                                      //
// ========================================================================== //

// Local variables
    int                            N = 10;
    bitpit::LIFOStack<ivector1D>           stack(5);

// Counters
    int                            i;

// ========================================================================== //
// OPENING MESSAGE                                                            //
// ========================================================================== //
    {
        // Scope variables ------------------------------------------------------ //
        // none

        // Output message ------------------------------------------------------- //
        cout << "================== TEST 000: LIFO stack demo ==================" << endl;

    }

// ========================================================================== //
// INSERT ELEMENTS INTO THE LIFO STACK                                        //
// ========================================================================== //
    {
        // Scope variables ------------------------------------------------------ //
        ivector1D        dummy(2, 0);

        // PUSH elements into the LIFO stack ------------------------------------ //
        for (i = 0; i < N; i++) {
            dummy[0] = i+1;
            dummy[1] = -dummy[0];
            cout << " * pushing element: " << dummy << endl;
            stack.push(dummy);
            stack.display(cout);
        } //next i

        // POP elements from the LIFO stack ------------------------------------- //
        for (i = 0; i < N; i++) {
            dummy = stack.pop();
            cout << " * popped element: " << dummy << endl;
            stack.display(cout);
        } //next i
    }

// ========================================================================== //
// CLOSING MESSAGE                                                            //
// ========================================================================== //
    {
        // Scope variables ------------------------------------------------------ //
        // none

        // Output message ------------------------------------------------------- //
        cout << "====================== TEST 000: done!! =======================" << endl;

    }

    return;
};
コード例 #20
0
ファイル: Thread.cpp プロジェクト: sfsy1989/j2me
address Thread::stack_base() const {
  const ExecutionStack::Raw stack(execution_stack());
  return (address)stack().field_base(
                          JavaStackDirection < 0 ? stack().length() : 0 );
}
コード例 #21
0
static int vector3_cross(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(cross(stack.get_vector3(1), stack.get_vector3(2)));
	return 1;
}
コード例 #22
0
ItemStack operator+(ItemStack const &is, sf::Uint32 const &toAdd)
{
    ItemStack stack(is);
    return stack += toAdd;
}
コード例 #23
0
static int vector3_new(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(vector3(stack.get_float(1), stack.get_float(2), stack.get_float(3)));
	return 1;
}
コード例 #24
0
ItemStack operator-(ItemStack const &is, sf::Uint32 const &toRemove)
{
    ItemStack stack(is);
    return stack -= toRemove;
}
コード例 #25
0
static int vector3_set_length(lua_State* L)
{
	LuaStack stack(L);
	set_length(stack.get_vector3(1), stack.get_float(2));
	return 0;
}
コード例 #26
0
ファイル: PredictiveParser.c プロジェクト: pamodbanjitha/LP
int main()
{
  char ip[20],r[20],st,an;
  int ir,ic,j=0,k;
  char t[5][6][10]={"$","$","TH","$","TH","$",
           "+TH","$","e","e","$","e",
           "$","$","FU","$","FU","$",
           "e","*FU","e","e","$","e",
           "$","$","(E)","$","i","$"};
  clrscr();
  printf("\nEnter any String(Append with $)");
  gets(ip);
  printf("Stack\tInput\tOutput\n\n");
  push("$E");
  display();
  printf("\t%s\n",ip);
  for(j=0;ip[j]!='\0';)
  {
  if(TOS()==an)
      {
    pop();
    display();
    display1(ip,j+1);
    printf("\tPOP\n");
    j++;
      }
    an=ip[j];
    st=TOS();
      if(st=='E')ir=0;
      else if(st=='H')ir=1;
      else if(st=='T')ir=2;
      else if(st=='U')ir=3;
      else if(st=='F')ir=4;
      else {
        error();
        break;
        }
      if(an=='+')ic=0;
      else if(an=='*')ic=1;
      else if(an=='(')ic=2;
      else if(an==')')ic=3;
      else if((an>='a'&&an<='z')||(an>='A'&&an<='Z')){ic=4;an='i';}
      else if(an=='$')ic=5;
      strcpy(r,strrev(t[ir][ic]));
      strrev(t[ir][ic]);
      pop();
      push(r);
      if(TOS()=='e')
      {
    pop();
    display();
    display1(ip,j);
    printf("\t%c->%c\n",st,238);
      }
      else{
      display();
      display1(ip,j);
      printf("\t%c->%s\n",st,t[ir][ic]);
      }
      if(TOS()=='$'&&an=='$')
      break;
      if(TOS()=='$'){
    error();
    break;
    }
      }
      k=strcmp(stack(),"$");
      if(k==0 && i==strlen(ip))
    printf("\n Given String is accepted");
    else
    printf("\n Given String is not accepted");
  return 0;
}
コード例 #27
0
static int vector3_angle(lua_State* L)
{
	LuaStack stack(L);
	stack.push_float(angle(stack.get_vector3(1), stack.get_vector3(2)));
	return 1;
}
コード例 #28
0
ファイル: pointer.c プロジェクト: Vrakfall/bspwm
void grab_pointer(pointer_action_t pac)
{
	PRINTF("grab pointer %u\n", pac);

	xcb_window_t win = XCB_NONE;
	xcb_point_t pos;

	query_pointer(&win, &pos);

	coordinates_t loc;
	if (locate_window(win, &loc)) {
		client_t *c = NULL;
		frozen_pointer->position = pos;
		frozen_pointer->action = pac;
		c = loc.node->client;
		frozen_pointer->monitor = loc.monitor;
		frozen_pointer->desktop = loc.desktop;
		frozen_pointer->node = loc.node;
		frozen_pointer->client = c;
		frozen_pointer->window = c->window;
		frozen_pointer->horizontal_fence = NULL;
		frozen_pointer->vertical_fence = NULL;

		switch (pac)  {
			case ACTION_FOCUS:
				if (loc.node != mon->desk->focus) {
					bool backup = pointer_follows_monitor;
					pointer_follows_monitor = false;
					focus_node(loc.monitor, loc.desktop, loc.node);
					pointer_follows_monitor = backup;
				} else if (focus_follows_pointer) {
					stack(loc.node, true);
				}
				frozen_pointer->action = ACTION_NONE;
				break;
			case ACTION_MOVE:
			case ACTION_RESIZE_SIDE:
			case ACTION_RESIZE_CORNER:
				if (IS_FLOATING(c)) {
					frozen_pointer->rectangle = c->floating_rectangle;
					frozen_pointer->is_tiled = false;
				} else if (IS_TILED(c)) {
					frozen_pointer->rectangle = c->tiled_rectangle;
					frozen_pointer->is_tiled = (pac == ACTION_MOVE || c->state == STATE_PSEUDO_TILED);
				} else {
					frozen_pointer->action = ACTION_NONE;
					return;
				}
				if (pac == ACTION_RESIZE_SIDE) {
					float W = frozen_pointer->rectangle.width;
					float H = frozen_pointer->rectangle.height;
					float ratio = W / H;
					float x = pos.x - frozen_pointer->rectangle.x;
					float y = pos.y - frozen_pointer->rectangle.y;
					float diag_a = ratio * y;
					float diag_b = W - diag_a;
					if (x < diag_a) {
						if (x < diag_b)
							frozen_pointer->side = SIDE_LEFT;
						else
							frozen_pointer->side = SIDE_BOTTOM;
					} else {
						if (x < diag_b)
							frozen_pointer->side = SIDE_TOP;
						else
							frozen_pointer->side = SIDE_RIGHT;
					}
				} else if (pac == ACTION_RESIZE_CORNER) {
					int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
					int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
					if (pos.x > mid_x) {
						if (pos.y > mid_y)
							frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
						else
							frozen_pointer->corner = CORNER_TOP_RIGHT;
					} else {
						if (pos.y > mid_y)
							frozen_pointer->corner = CORNER_BOTTOM_LEFT;
						else
							frozen_pointer->corner = CORNER_TOP_LEFT;
					}
				}
				if (frozen_pointer->is_tiled) {
					if (pac == ACTION_RESIZE_SIDE) {
						switch (frozen_pointer->side) {
							case SIDE_TOP:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								break;
							case SIDE_RIGHT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case SIDE_BOTTOM:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								break;
							case SIDE_LEFT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
						}
					} else if (pac == ACTION_RESIZE_CORNER) {
						switch (frozen_pointer->corner) {
							case CORNER_TOP_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
							case CORNER_TOP_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case CORNER_BOTTOM_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
								break;
							case CORNER_BOTTOM_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
								break;
						}
					}
					if (frozen_pointer->horizontal_fence != NULL)
						frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
					if (frozen_pointer->vertical_fence != NULL)
						frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
				}
				break;
			case ACTION_NONE:
				break;
		}
	} else {
		if (pac == ACTION_FOCUS) {
			monitor_t *m = monitor_from_point(pos);
			if (m != NULL && m != mon)
				focus_node(m, m->desk, m->desk->focus);
		}
		frozen_pointer->action = ACTION_NONE;
	}
}
コード例 #29
0
static int vector3_backward(lua_State* L)
{
	LuaStack stack(L);
	stack.push_vector3(VECTOR3_BACKWARD);
	return 1;
}
コード例 #30
0
GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */)
{
    BYTE *glyph;

    tt_flags = NULL;
    xcoor = NULL;
    ycoor = NULL;
    epts_ctr = NULL;
    stack_depth = 0;
    pdf_mode = font->target_type < 0;

    /* Get a pointer to the data. */
    glyph = find_glyph_data( font, charindex );

    /* If the character is blank, it has no bounding box, */
    /* otherwise read the bounding box. */
    if ( glyph == (BYTE*)NULL )
    {
        llx=lly=urx=ury=0;      /* A blank char has an all zero BoundingBox */
        num_ctr=0;              /* Set this for later if()s */
    }
    else
    {
        /* Read the number of contours. */
        num_ctr = getSHORT(glyph);

        /* Read PostScript bounding box. */
        llx = getFWord(glyph + 2);
        lly = getFWord(glyph + 4);
        urx = getFWord(glyph + 6);
        ury = getFWord(glyph + 8);

        /* Advance the pointer. */
        glyph += 10;
    }

    /* If it is a simple character, load its data. */
    if (num_ctr > 0)
    {
        load_char(font, glyph);
    }
    else
    {
        num_pts=0;
    }

    /* Consult the horizontal metrics table to determine */
    /* the character width. */
    if ( charindex < font->numberOfHMetrics )
    {
        advance_width = getuFWord( font->hmtx_table + (charindex * 4) );
    }
    else
    {
        advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) );
    }

    /* Execute setcachedevice in order to inform the font machinery */
    /* of the character bounding box and advance width. */
    stack(stream, 7);
    if (pdf_mode)
    {
        if (!embedded) {
            stream.printf("%d 0 %d %d %d %d d1\n",
                          topost(advance_width),
                          topost(llx), topost(lly), topost(urx), topost(ury) );
        }
    }
    else if (font->target_type == PS_TYPE_42_3_HYBRID)
    {
        stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n",
                      topost(advance_width),
                      topost(llx), topost(lly), topost(urx), topost(ury) );
    }
    else
    {
        stream.printf("%d 0 %d %d %d %d _sc\n",
                      topost(advance_width),
                      topost(llx), topost(lly), topost(urx), topost(ury) );
    }

    /* If it is a simple glyph, convert it, */
    /* otherwise, close the stack business. */
    if ( num_ctr > 0 )          /* simple */
    {
        PSConvert(stream);
    }
    else if ( num_ctr < 0 )     /* composite */
    {
        do_composite(stream, font, glyph);
    }

    if (font->target_type == PS_TYPE_42_3_HYBRID)
    {
        stream.printf("\ngrestore\n");
    }

    stack_end(stream);
}