예제 #1
0
파일: ttf.cpp 프로젝트: alexbevi/scummvm
int TTFFont::getKerningOffset(uint32 left, uint32 right) const {
	if (!_hasKerning)
		return 0;

	assureCached(left);
	assureCached(right);

	FT_UInt leftGlyph, rightGlyph;
	GlyphCache::const_iterator glyphEntry;

	glyphEntry = _glyphs.find(left);
	if (glyphEntry != _glyphs.end()) {
		leftGlyph = glyphEntry->_value.slot;
	} else {
		return 0;
	}

	glyphEntry = _glyphs.find(right);
	if (glyphEntry != _glyphs.end()) {
		rightGlyph = glyphEntry->_value.slot;
	} else {
		return 0;
	}

	if (!leftGlyph || !rightGlyph)
		return 0;

	FT_Vector kerningVector;
	FT_Get_Kerning(_face, leftGlyph, rightGlyph, FT_KERNING_DEFAULT, &kerningVector);
	return (kerningVector.x / 64);
}
예제 #2
0
파일: ttf.cpp 프로젝트: alexbevi/scummvm
int TTFFont::getCharWidth(uint32 chr) const {
	assureCached(chr);
	GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
	if (glyphEntry == _glyphs.end())
		return 0;
	else
		return glyphEntry->_value.advance;
}
예제 #3
0
파일: ttf.cpp 프로젝트: alexbevi/scummvm
Common::Rect TTFFont::getBoundingBox(uint32 chr) const {
	assureCached(chr);
	GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
	if (glyphEntry == _glyphs.end()) {
		return Common::Rect();
	} else {
		const int xOffset = glyphEntry->_value.xOffset;
		const int yOffset = glyphEntry->_value.yOffset;
		const Graphics::Surface &image = glyphEntry->_value.image;
		return Common::Rect(xOffset, yOffset, xOffset + image.w, yOffset + image.h);
	}
}
예제 #4
0
Common::InSaveFile *DefaultSaveFileManager::openRawFile(const Common::String &filename) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return nullptr;

	SaveFileCache::const_iterator file = _saveFileCache.find(filename);
	if (file == _saveFileCache.end()) {
		return nullptr;
	} else {
		// Open the file for loading.
		Common::SeekableReadStream *sf = file->_value.createReadStream();
		return sf;
	}
}
예제 #5
0
Common::StringArray DefaultSaveFileManager::listSavefiles(const Common::String &pattern) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return Common::StringArray();

	Common::HashMap<Common::String, bool> locked;
	for (Common::StringArray::const_iterator i = _lockedFiles.begin(), end = _lockedFiles.end(); i != end; ++i) {
		locked[*i] = true;
	}

	Common::StringArray results;
	for (SaveFileCache::const_iterator file = _saveFileCache.begin(), end = _saveFileCache.end(); file != end; ++file) {
		if (!locked.contains(file->_key) && file->_key.matchString(pattern, true)) {
			results.push_back(file->_key);
		}
	}
	return results;
}
예제 #6
0
bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return false;
	
#ifdef USE_LIBCURL
	// Update file's timestamp
	Common::HashMap<Common::String, uint32> timestamps = loadTimestamps();
	Common::HashMap<Common::String, uint32>::iterator it = timestamps.find(filename);
	if (it != timestamps.end()) {
		timestamps.erase(it);
		saveTimestamps(timestamps);
	}
#endif

	// Obtain node if exists.
	SaveFileCache::const_iterator file = _saveFileCache.find(filename);
	if (file == _saveFileCache.end()) {
		return false;
	} else {
		const Common::FSNode fileNode = file->_value;
		// Remove from cache, this invalidates the 'file' iterator.
		_saveFileCache.erase(file);
		file = _saveFileCache.end();

		// FIXME: remove does not exist on all systems. If your port fails to
		// compile because of this, please let us know (scummvm-devel).
		// There is a nicely portable workaround, too: Make this method overloadable.
		if (remove(fileNode.getPath().c_str()) != 0) {
#ifndef _WIN32_WCE
			if (errno == EACCES)
				setError(Common::kWritePermissionDenied, "Search or write permission denied: "+fileNode.getName());

			if (errno == ENOENT)
				setError(Common::kPathDoesNotExist, "removeSavefile: '"+fileNode.getName()+"' does not exist or path is invalid");
#endif
			return false;
		} else {
			return true;
		}
	}
}
예제 #7
0
Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const Common::String &filename, bool compress) {
	// Assure the savefile name cache is up-to-date.
	const Common::String savePathName = getSavePath();
	assureCached(savePathName);
	if (getError().getCode() != Common::kNoError)
		return nullptr;

	for (Common::StringArray::const_iterator i = _lockedFiles.begin(), end = _lockedFiles.end(); i != end; ++i) {
		if (filename == *i) {
			return nullptr; //file is locked, no saving available
		}
	}

#ifdef USE_LIBCURL
	// Update file's timestamp
	Common::HashMap<Common::String, uint32> timestamps = loadTimestamps();
	timestamps[filename] = INVALID_TIMESTAMP;
	saveTimestamps(timestamps);
#endif

	// Obtain node.
	SaveFileCache::const_iterator file = _saveFileCache.find(filename);
	Common::FSNode fileNode;

	// If the file did not exist before, we add it to the cache.
	if (file == _saveFileCache.end()) {
		const Common::FSNode savePath(savePathName);
		fileNode = savePath.getChild(filename);
	} else {
		fileNode = file->_value;
	}

	// Open the file for saving.
	Common::WriteStream *const sf = fileNode.createWriteStream();
	Common::OutSaveFile *const result = new Common::OutSaveFile(compress ? Common::wrapCompressedWriteStream(sf) : sf);

	// Add file to cache now that it exists.
	_saveFileCache[filename] = Common::FSNode(fileNode.getPath());

	return result;
}
예제 #8
0
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const Common::String &filename) {
	// Assure the savefile name cache is up-to-date.
	assureCached(getSavePath());
	if (getError().getCode() != Common::kNoError)
		return nullptr;

	for (Common::StringArray::const_iterator i = _lockedFiles.begin(), end = _lockedFiles.end(); i != end; ++i) {
		if (filename == *i) {
			return nullptr; //file is locked, no loading available
		}
	}

	SaveFileCache::const_iterator file = _saveFileCache.find(filename);
	if (file == _saveFileCache.end()) {
		return nullptr;
	} else {
		// Open the file for loading.
		Common::SeekableReadStream *sf = file->_value.createReadStream();
		return Common::wrapCompressedReadStream(sf);
	}
}
예제 #9
0
파일: ttf.cpp 프로젝트: alexbevi/scummvm
void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
	assureCached(chr);
	GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
	if (glyphEntry == _glyphs.end())
		return;

	const Glyph &glyph = glyphEntry->_value;

	x += glyph.xOffset;
	y += glyph.yOffset;

	if (x > dst->w)
		return;
	if (y > dst->h)
		return;

	int w = glyph.image.w;
	int h = glyph.image.h;

	const uint8 *srcPos = (const uint8 *)glyph.image.getPixels();

	// Make sure we are not drawing outside the screen bounds
	if (x < 0) {
		srcPos -= x;
		w += x;
		x = 0;
	}

	if (x + w > dst->w)
		w = dst->w - x;

	if (w <= 0)
		return;

	if (y < 0) {
		srcPos -= y * glyph.image.pitch;
		h += y;
		y = 0;
	}

	if (y + h > dst->h)
		h = dst->h - y;

	if (h <= 0)
		return;

	uint8 *dstPos = (uint8 *)dst->getBasePtr(x, y);

	if (dst->format.bytesPerPixel == 1) {
		for (int cy = 0; cy < h; ++cy) {
			uint8 *rDst = dstPos;
			const uint8 *src = srcPos;

			for (int cx = 0; cx < w; ++cx) {
				// We assume a 1Bpp mode is a color indexed mode, thus we can
				// not take advantage of anti-aliasing here.
				if (*src >= 0x80)
					*rDst = color;

				++rDst;
				++src;
			}

			dstPos += dst->pitch;
			srcPos += glyph.image.pitch;
		}
	} else if (dst->format.bytesPerPixel == 2) {
		renderGlyph<uint16>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
	} else if (dst->format.bytesPerPixel == 4) {
		renderGlyph<uint32>(dstPos, dst->pitch, srcPos, glyph.image.pitch, w, h, color, dst->format);
	}
}